mirror of
https://github.com/bellingcat/osm-search.git
synced 2026-06-08 03:28:33 +03:00
Revise custom feature selector, API methods
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
<title>Bellingcat OpenStreetMap search</title>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@mdi/font@latest/css/materialdesignicons.min.css">
|
||||
<script defer data-domain="osm.baarle-hertog.xyz" src="https://plausible.io/js/script.js"></script>
|
||||
<script defer data-domain="osm-search.bellingcat.com" src="https://plausible.io/js/script.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
|
||||
@@ -31,6 +31,9 @@ export default {
|
||||
SearchControls,
|
||||
GoogleLogin,
|
||||
},
|
||||
mounted() {
|
||||
this.$store.dispatch("getKeys");
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
124
frontend/src/components/FeatureCustom.vue
Normal file
124
frontend/src/components/FeatureCustom.vue
Normal file
@@ -0,0 +1,124 @@
|
||||
<template>
|
||||
<v-card style="margin-top: 1em">
|
||||
<v-card-title>Custom feature</v-card-title>
|
||||
<v-card-text>
|
||||
<v-row v-for="(f, i) in filters" :key="'row' + i">
|
||||
<v-col cols="3"
|
||||
><v-select
|
||||
v-if="i == 0"
|
||||
label="Feature type"
|
||||
:items="queryTypes"
|
||||
v-model="selectedQueryType"
|
||||
></v-select>
|
||||
<v-select
|
||||
v-else-if="i == 1"
|
||||
label="Condition"
|
||||
:items="['OR', 'AND']"
|
||||
v-model="method"
|
||||
></v-select> </v-col
|
||||
><v-col>
|
||||
<!-- Text field for OSM parameter -->
|
||||
<v-combobox
|
||||
class="code"
|
||||
label="OSM key"
|
||||
v-model="f.parameter"
|
||||
:items="$store.state.osmKeys"
|
||||
@input="getValues"
|
||||
></v-combobox
|
||||
></v-col>
|
||||
<v-col>
|
||||
<!-- Dropdown for type of comparison between parameter and value -->
|
||||
<v-select
|
||||
label=""
|
||||
:items="[
|
||||
'=',
|
||||
'!=',
|
||||
'>',
|
||||
'<',
|
||||
'>=',
|
||||
'<=',
|
||||
'starts with',
|
||||
'ends with',
|
||||
'contains',
|
||||
'does not contain',
|
||||
'is null',
|
||||
'is not null',
|
||||
]"
|
||||
v-model="f.comparison"
|
||||
></v-select>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<!-- Text field for parameter value -->
|
||||
<v-combobox
|
||||
class="code"
|
||||
label="OSM value"
|
||||
v-model="f.value"
|
||||
:items="$store.state.selectedKeyValues"
|
||||
:disabled="
|
||||
f.comparison == 'is null' || f.comparison == 'is not null'
|
||||
"
|
||||
></v-combobox>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-btn color="secondary" text @click="addFilter">Add condition</v-btn>
|
||||
<v-btn style="margin-left: auto" color="primary" text @click="addCustom"
|
||||
>Add custom feature</v-btn
|
||||
>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "FeatureCustom",
|
||||
data() {
|
||||
return {
|
||||
queryTypes: ["point", "line", "polygon"],
|
||||
selectedQueryType: "point",
|
||||
method: "OR",
|
||||
filters: [
|
||||
{
|
||||
parameter: "",
|
||||
comparison: "=",
|
||||
value: "",
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
addCustom() {
|
||||
this.$store.commit("updateSelected", [
|
||||
...this.$store.state.selected,
|
||||
{
|
||||
name: "Custom filter",
|
||||
type: this.selectedQueryType,
|
||||
filters: this.filters.filter((v) => v.parameter != ""),
|
||||
method: this.method,
|
||||
},
|
||||
]);
|
||||
|
||||
this.method = "OR";
|
||||
this.filters = [
|
||||
{
|
||||
parameter: "",
|
||||
comparison: "=",
|
||||
value: "",
|
||||
},
|
||||
];
|
||||
this.selectedQueryType = "point";
|
||||
},
|
||||
addFilter() {
|
||||
this.filters.push({
|
||||
parameter: "",
|
||||
comparison: "=",
|
||||
value: "",
|
||||
});
|
||||
},
|
||||
getValues(v) {
|
||||
this.$store.dispatch("getValues", v);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -11,33 +11,12 @@
|
||||
<v-card-title>Selected features</v-card-title>
|
||||
<v-card-text>
|
||||
<v-col>
|
||||
<v-card
|
||||
<FeatureView
|
||||
v-for="(query, i) in $store.state.selected"
|
||||
:key="query.name + query.type"
|
||||
close
|
||||
style="margin-bottom: 1em"
|
||||
>
|
||||
<v-card-title
|
||||
:color="
|
||||
query.type == 'point'
|
||||
? '#8BC34A'
|
||||
: query.type == 'line'
|
||||
? '#00BCD4'
|
||||
: '#FFC107'
|
||||
"
|
||||
>
|
||||
{{ query.name }}
|
||||
<span class="type">({{ query.type }})</span>
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<span class="code">
|
||||
{{ query.filter }}
|
||||
</span>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-btn color="red" text @click="remove(i)"> Remove </v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
:query="query"
|
||||
:index="i"
|
||||
/>
|
||||
</v-col>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
@@ -64,44 +43,25 @@
|
||||
>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
<v-card style="margin-top: 1em">
|
||||
<v-card-title>Custom feature</v-card-title>
|
||||
<v-card-text>
|
||||
<v-row>
|
||||
<v-col cols="3"
|
||||
><v-select
|
||||
label="Feature type"
|
||||
:items="queryTypes"
|
||||
v-model="selectedQueryType"
|
||||
></v-select> </v-col
|
||||
><v-col>
|
||||
<v-text-field
|
||||
class="code"
|
||||
label="Filter statement"
|
||||
v-model="customFilter"
|
||||
></v-text-field>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-btn color="primary" text @click="addCustom">Add</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
<FeatureCustom />
|
||||
</v-col>
|
||||
</v-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import queries from "./queries.js";
|
||||
import FeatureView from "./FeatureView.vue";
|
||||
import FeatureCustom from "./FeatureCustom.vue";
|
||||
|
||||
export default {
|
||||
name: "FeatureSelector",
|
||||
components: {
|
||||
FeatureView,
|
||||
FeatureCustom,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
queries,
|
||||
queryTypes: ["point", "line", "polygon"],
|
||||
selectedQueryType: "point",
|
||||
customFilter: "",
|
||||
accepting: false,
|
||||
};
|
||||
},
|
||||
@@ -127,28 +87,6 @@ export default {
|
||||
startDrag(e, item) {
|
||||
e.dataTransfer.setData("object", JSON.stringify(item));
|
||||
},
|
||||
remove(index) {
|
||||
let value = this.$store.state.selected;
|
||||
let newValue = [
|
||||
...value.slice(0, index),
|
||||
...value.slice(index + 1, value.length),
|
||||
];
|
||||
console.log(index, value, newValue);
|
||||
this.$store.commit("updateSelected", newValue);
|
||||
},
|
||||
addCustom() {
|
||||
this.$store.commit("updateSelected", [
|
||||
...this.$store.state.selected,
|
||||
{
|
||||
name: "Custom filter",
|
||||
type: this.selectedQueryType,
|
||||
filter: this.customFilter,
|
||||
},
|
||||
]);
|
||||
|
||||
this.customFilter = "";
|
||||
this.selectedQueryType = "point";
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
49
frontend/src/components/FeatureView.vue
Normal file
49
frontend/src/components/FeatureView.vue
Normal file
@@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<v-card close style="margin-bottom: 1em">
|
||||
<v-card-title>
|
||||
{{ query.name }}
|
||||
<span class="type">({{ query.type }})</span>
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<div v-for="(f, i) in query.filters" :key="i">
|
||||
<div class="code">
|
||||
{{ (i == 0 ? "" : query.method + " ") + f.parameter
|
||||
}}<a
|
||||
:href="'https://wiki.openstreetmap.org/wiki/Key:' + f.parameter"
|
||||
target="_blank"
|
||||
class="super"
|
||||
>
|
||||
<v-icon x-small>mdi-open-in-new</v-icon></a
|
||||
>
|
||||
{{ f.comparison }} {{ f.value }}
|
||||
</div>
|
||||
</div>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-btn color="red" text @click="remove(index)"> Remove </v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "FeatureView",
|
||||
props: {
|
||||
query: Object,
|
||||
index: Number,
|
||||
},
|
||||
methods: {
|
||||
remove(index) {
|
||||
this.$store.commit("removeSelected", index);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.super {
|
||||
font-size: 0.8em;
|
||||
vertical-align: super;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
@@ -2,177 +2,503 @@ export default [
|
||||
{
|
||||
name: "Power pylon",
|
||||
type: "point",
|
||||
filter: "power = 'tower' OR power = 'pole'",
|
||||
method: "OR",
|
||||
filters: [
|
||||
{
|
||||
parameter: "power",
|
||||
comparison: "=",
|
||||
value: "tower",
|
||||
},
|
||||
{
|
||||
parameter: "power",
|
||||
comparison: "=",
|
||||
value: "pole",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Public transport stop",
|
||||
type: "point",
|
||||
filter: "(public_transport IS NOT null OR highway='bus_stop')",
|
||||
method: "OR",
|
||||
filters: [
|
||||
{
|
||||
parameter: "public_transport",
|
||||
comparison: "is not null",
|
||||
},
|
||||
{
|
||||
parameter: "highway",
|
||||
comparison: "=",
|
||||
value: "bus_stop",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Church",
|
||||
type: "point",
|
||||
filter: "amenity = 'place_of_worship'",
|
||||
method: "OR",
|
||||
filters: [
|
||||
{
|
||||
parameter: "amenity",
|
||||
comparison: "=",
|
||||
value: "place_of_worship",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Hospital",
|
||||
type: "point",
|
||||
filter: "amenity = 'hospital'",
|
||||
method: "OR",
|
||||
filters: [
|
||||
{
|
||||
parameter: "amenity",
|
||||
comparison: "=",
|
||||
value: "hospital",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Military",
|
||||
type: "point",
|
||||
filter: "military IS NOT null OR landuse = 'military'",
|
||||
method: "OR",
|
||||
filters: [
|
||||
{
|
||||
parameter: "military",
|
||||
comparison: "is not null",
|
||||
},
|
||||
{
|
||||
parameter: "landuse",
|
||||
comparison: "=",
|
||||
value: "military",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Restaurant",
|
||||
type: "point",
|
||||
filter:
|
||||
"amenity = 'restaurant' OR amenity = 'cafe' OR amenity = 'pub' OR amenity = 'fast_food'",
|
||||
method: "OR",
|
||||
filters: [
|
||||
{
|
||||
parameter: "amenity",
|
||||
comparison: "=",
|
||||
value: "restaurant",
|
||||
},
|
||||
{
|
||||
parameter: "amenity",
|
||||
comparison: "=",
|
||||
value: "cafe",
|
||||
},
|
||||
{
|
||||
parameter: "amenity",
|
||||
comparison: "=",
|
||||
value: "pub",
|
||||
},
|
||||
{
|
||||
parameter: "amenity",
|
||||
comparison: "=",
|
||||
value: "fast_food",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Waterway",
|
||||
type: "line",
|
||||
filter: "waterway IS NOT null",
|
||||
method: "OR",
|
||||
filters: [
|
||||
{
|
||||
parameter: "waterway",
|
||||
comparison: "is not null",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Road",
|
||||
type: "line",
|
||||
filter: "highway IS NOT null",
|
||||
method: "OR",
|
||||
filters: [
|
||||
{
|
||||
parameter: "highway",
|
||||
comparison: "is not null",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Railroad",
|
||||
type: "line",
|
||||
filter: "railway IS NOT null",
|
||||
method: "OR",
|
||||
filters: [
|
||||
{
|
||||
parameter: "railway",
|
||||
comparison: "is not null",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Bridge",
|
||||
type: "line",
|
||||
filter: "bridge IS NOT null",
|
||||
method: "OR",
|
||||
filters: [
|
||||
{
|
||||
parameter: "bridge",
|
||||
comparison: "is not null",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Road (motorway)",
|
||||
type: "line",
|
||||
filter: "highway = 'motorway' OR highway = 'motorway_link'",
|
||||
method: "OR",
|
||||
filters: [
|
||||
{
|
||||
parameter: "highway",
|
||||
comparison: "=",
|
||||
value: "motorway",
|
||||
},
|
||||
{
|
||||
parameter: "highway",
|
||||
comparison: "=",
|
||||
value: "motorway_link",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Road (primary)",
|
||||
type: "line",
|
||||
filter: "highway = 'primary' OR highway = 'primary_link'",
|
||||
method: "OR",
|
||||
filters: [
|
||||
{
|
||||
parameter: "highway",
|
||||
comparison: "=",
|
||||
value: "primary",
|
||||
},
|
||||
{
|
||||
parameter: "highway",
|
||||
comparison: "=",
|
||||
value: "primary_link",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Road (secondary)",
|
||||
type: "line",
|
||||
filter: "highway = 'secondary' OR highway = 'secondary_link",
|
||||
method: "OR",
|
||||
filters: [
|
||||
{
|
||||
parameter: "highway",
|
||||
comparison: "=",
|
||||
value: "secondary",
|
||||
},
|
||||
{
|
||||
parameter: "highway",
|
||||
comparison: "=",
|
||||
value: "secondary_link",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Road (residential)",
|
||||
type: "line",
|
||||
filter: "highway = 'residential'",
|
||||
method: "OR",
|
||||
filters: [
|
||||
{
|
||||
parameter: "highway",
|
||||
comparison: "=",
|
||||
value: "residential",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Unpaved road",
|
||||
type: "line",
|
||||
filter: "surface = 'unpaved'",
|
||||
method: "OR",
|
||||
filters: [
|
||||
{
|
||||
parameter: "surface",
|
||||
comparison: "=",
|
||||
value: "unpaved",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "1-lane road",
|
||||
type: "line",
|
||||
filter: "tags->'lanes' = '1'",
|
||||
method: "OR",
|
||||
filters: [
|
||||
{
|
||||
parameter: "lanes",
|
||||
comparison: "=",
|
||||
value: "1",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "2-lane road",
|
||||
type: "line",
|
||||
filter: "tags->'lanes' = '2'",
|
||||
method: "OR",
|
||||
filters: [
|
||||
{
|
||||
parameter: "lanes",
|
||||
comparison: "=",
|
||||
value: "2",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "3-lane road",
|
||||
type: "line",
|
||||
filter: "tags->'lanes' = '3'",
|
||||
method: "OR",
|
||||
filters: [
|
||||
{
|
||||
parameter: "lanes",
|
||||
comparison: "=",
|
||||
value: "3",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "4-lane road",
|
||||
type: "line",
|
||||
filter: "tags->'lanes' = '4'",
|
||||
method: "OR",
|
||||
filters: [
|
||||
{
|
||||
parameter: "lanes",
|
||||
comparison: "=",
|
||||
value: "4",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "5-lane road",
|
||||
type: "line",
|
||||
filter: "tags->'lanes' = '5'",
|
||||
method: "OR",
|
||||
filters: [
|
||||
{
|
||||
parameter: "lanes",
|
||||
comparison: "=",
|
||||
value: "5",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "6-lane road",
|
||||
type: "line",
|
||||
filter: "tags->'lanes' = '6'",
|
||||
method: "OR",
|
||||
filters: [
|
||||
{
|
||||
parameter: "lanes",
|
||||
comparison: "=",
|
||||
value: "6",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Sidewalk",
|
||||
type: "line",
|
||||
method: "AND",
|
||||
filters: [
|
||||
{
|
||||
parameter: "sidewalk",
|
||||
comparison: "is not null",
|
||||
},
|
||||
{
|
||||
parameter: "sidewalk",
|
||||
comparison: "!=",
|
||||
value: "no",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Cliff",
|
||||
type: "line",
|
||||
filter: "planet_osm_line.natural = 'cliff'",
|
||||
method: "OR",
|
||||
filters: [
|
||||
{
|
||||
parameter: "natural",
|
||||
comparison: "=",
|
||||
value: "cliff",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Park",
|
||||
type: "polygon",
|
||||
filter: "leisure = 'park'",
|
||||
method: "OR",
|
||||
filters: [
|
||||
{
|
||||
parameter: "leisure",
|
||||
comparison: "=",
|
||||
value: "park",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Industrial area",
|
||||
type: "polygon",
|
||||
filter: "landuse = 'industrial'",
|
||||
method: "OR",
|
||||
filters: [
|
||||
{
|
||||
parameter: "landuse",
|
||||
comparison: "=",
|
||||
value: "industrial",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Body of water",
|
||||
type: "polygon",
|
||||
filter: "water IS NOT null",
|
||||
method: "OR",
|
||||
filters: [
|
||||
{
|
||||
parameter: "water",
|
||||
comparison: "is not null",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Forest",
|
||||
type: "polygon",
|
||||
filter: "landuse = 'forest' OR planet_osm_polygon.natural = 'forest'",
|
||||
method: "OR",
|
||||
filters: [
|
||||
{
|
||||
parameter: "landuse",
|
||||
comparison: "=",
|
||||
value: "forest",
|
||||
},
|
||||
{
|
||||
parameter: "natural",
|
||||
comparison: "=",
|
||||
value: "forest",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Farmland",
|
||||
type: "polygon",
|
||||
filter: "landuse = 'farmland'",
|
||||
method: "OR",
|
||||
filters: [
|
||||
{
|
||||
parameter: "landuse",
|
||||
comparison: "=",
|
||||
value: "farmland",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Building",
|
||||
type: "polygon",
|
||||
filter: "building IS NOT null",
|
||||
method: "OR",
|
||||
filters: [
|
||||
{
|
||||
parameter: "building",
|
||||
comparison: "is not null",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Building (1 story)",
|
||||
type: "polygon",
|
||||
filter: "tags->'building:levels' = '1'",
|
||||
method: "OR",
|
||||
filters: [
|
||||
{
|
||||
parameter: "building:levels",
|
||||
comparison: "=",
|
||||
value: "1",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Building (2 story)",
|
||||
type: "polygon",
|
||||
filter: "tags->'building:levels' = '2'",
|
||||
method: "OR",
|
||||
filters: [
|
||||
{
|
||||
parameter: "building:levels",
|
||||
comparison: "=",
|
||||
value: "2",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Building (3 story)",
|
||||
type: "polygon",
|
||||
filter: "tags->'building:levels' = '3'",
|
||||
method: "OR",
|
||||
filters: [
|
||||
{
|
||||
parameter: "building:levels",
|
||||
comparison: "=",
|
||||
value: "3",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Building (4 story)",
|
||||
type: "polygon",
|
||||
filter: "tags->'building:levels' = '4'",
|
||||
method: "OR",
|
||||
filters: [
|
||||
{
|
||||
parameter: "building:levels",
|
||||
comparison: "=",
|
||||
value: "4",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Building (5+ stories)",
|
||||
name: "Building (5-9 stories)",
|
||||
type: "polygon",
|
||||
filter: "(tags->'building:levels')::integer >= 5",
|
||||
method: "AND",
|
||||
filters: [
|
||||
{
|
||||
parameter: "building:levels",
|
||||
comparison: ">=",
|
||||
value: "5",
|
||||
cast: "cast_to_float",
|
||||
},
|
||||
{
|
||||
parameter: "building:levels",
|
||||
comparison: "<",
|
||||
value: "10",
|
||||
cast: "cast_to_float",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Building (10+ stories)",
|
||||
type: "polygon",
|
||||
method: "OR",
|
||||
filters: [
|
||||
{
|
||||
parameter: "building:levels",
|
||||
comparison: ">=",
|
||||
value: "10",
|
||||
cast: "cast_to_float",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Beach",
|
||||
type: "polygon",
|
||||
filter: "planet_osm_polygon.natural = 'beach'",
|
||||
method: "OR",
|
||||
filters: [
|
||||
{
|
||||
parameter: "natural",
|
||||
comparison: "=",
|
||||
value: "beach",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Military",
|
||||
type: "polygon",
|
||||
filter: "military IS NOT null OR landuse = 'military'",
|
||||
method: "OR",
|
||||
filters: [
|
||||
{
|
||||
parameter: "military",
|
||||
comparison: "is not null",
|
||||
},
|
||||
{
|
||||
parameter: "landuse",
|
||||
comparison: "=",
|
||||
value: "military",
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
@@ -19,6 +19,8 @@ export default new Vuex.Store({
|
||||
mapCenter: [42.2, -71.7],
|
||||
mapZoom: 8,
|
||||
responseTime: null,
|
||||
osmKeys: [],
|
||||
selectedKeyValues: [],
|
||||
},
|
||||
mutations: {
|
||||
initializeCredentials(state) {
|
||||
@@ -49,6 +51,14 @@ export default new Vuex.Store({
|
||||
updateSelected(state, value) {
|
||||
state.selected = [...value];
|
||||
},
|
||||
removeSelected(state, index) {
|
||||
let value = state.selected;
|
||||
let newValue = [
|
||||
...value.slice(0, index),
|
||||
...value.slice(index + 1, value.length),
|
||||
];
|
||||
state.selected = newValue;
|
||||
},
|
||||
setSearchResults(state, data) {
|
||||
state.searchResults = data;
|
||||
},
|
||||
@@ -82,8 +92,51 @@ export default new Vuex.Store({
|
||||
setResponseTime(state, t) {
|
||||
state.responseTime = t;
|
||||
},
|
||||
setKeys(state, keys) {
|
||||
state.osmKeys = keys;
|
||||
},
|
||||
setSelectedKeyValues(state, values) {
|
||||
state.selectedKeyValues = values;
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
getKeys({ commit }) {
|
||||
fetch(
|
||||
"https://taginfo.openstreetmap.org/api/4/keys/all?page=1&rp=200&filter=in_wiki&sortname=count_all&sortorder=desc"
|
||||
)
|
||||
.then((d) => {
|
||||
if (d.status != 200) {
|
||||
return Promise.reject(Error(d.status));
|
||||
}
|
||||
return d.json();
|
||||
})
|
||||
.then((data) => {
|
||||
commit(
|
||||
"setKeys",
|
||||
data.data.map((d) => d.key)
|
||||
);
|
||||
});
|
||||
},
|
||||
getValues({ commit }, v) {
|
||||
commit("setSelectedKeyValues", []);
|
||||
|
||||
fetch(
|
||||
"https://taginfo.openstreetmap.org/api/4/key/values?rp=50&sortname=count_all&sortorder=desc&key=" +
|
||||
v
|
||||
)
|
||||
.then((d) => {
|
||||
if (d.status != 200) {
|
||||
return Promise.reject(Error(d.status));
|
||||
}
|
||||
return d.json();
|
||||
})
|
||||
.then((data) => {
|
||||
commit(
|
||||
"setSelectedKeyValues",
|
||||
data.data.filter((d) => d.fraction > 0.01).map((d) => d.value)
|
||||
);
|
||||
});
|
||||
},
|
||||
search({ state, commit }) {
|
||||
let bbox = state.bbox;
|
||||
let range = state.range;
|
||||
@@ -94,7 +147,8 @@ export default new Vuex.Store({
|
||||
let time1 = performance.now();
|
||||
|
||||
fetch(
|
||||
`https://api.baarle-hertog.xyz/intersection?l=${bbox[0][1]}&b=${bbox[0][0]}&r=${bbox[1][1]}&t=${bbox[1][0]}&buffer=${range}&filters=${filters}`,
|
||||
// `https://api.osm-search.bellingcat.com/intersection?l=${bbox[0][1]}&b=${bbox[0][0]}&r=${bbox[1][1]}&t=${bbox[1][0]}&buffer=${range}&filters=${filters}`,
|
||||
`http://localhost:5050/intersection?l=${bbox[0][1]}&b=${bbox[0][0]}&r=${bbox[1][1]}&t=${bbox[1][0]}&buffer=${range}&filters=${filters}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: "Bearer " + state.token,
|
||||
|
||||
Reference in New Issue
Block a user