UK-themes: add inspire polygons to detect addresses with, various small fixes

This commit is contained in:
Pieter Vander Vennet 2021-11-05 01:19:27 +01:00
parent be3ac93eca
commit 2c46645581
7 changed files with 71 additions and 23 deletions

View file

@ -54,10 +54,10 @@ export class ExtraFunction {
private static readonly OverlapFunc = new ExtraFunction( private static readonly OverlapFunc = new ExtraFunction(
{ {
name: "overlapWith", name: "overlapWith",
doc: "Gives a list of features from the specified layer which this feature (partly) overlaps with. " + doc: "Gives a list of features from the specified layer which this feature (partly) overlaps with. A point which is embedded in the feature is detected as well." +
"If the current feature is a point, all features that embed the point are given. " + "If the current feature is a point, all features that this point is embeded in are given.\n\n" +
"The returned value is `{ feat: GeoJSONFeature, overlap: number}[]` where `overlap` is the overlapping surface are (in m²) for areas, the overlapping length (in meter) if the current feature is a line or `undefined` if the current feature is a point.\n" + "The returned value is `{ feat: GeoJSONFeature, overlap: number}[]` where `overlap` is the overlapping surface are (in m²) for areas, the overlapping length (in meter) if the current feature is a line or `undefined` if the current feature is a point.\n" +
"The resulting list is sorted in descending order by overlap. The feature with the most overlap will thus be the first in the list" + "The resulting list is sorted in descending order by overlap. The feature with the most overlap will thus be the first in the list\n" +
"\n" + "\n" +
"For example to get all objects which overlap or embed from a layer, use `_contained_climbing_routes_properties=feat.overlapWith('climbing_route')`", "For example to get all objects which overlap or embed from a layer, use `_contained_climbing_routes_properties=feat.overlapWith('climbing_route')`",
args: ["...layerIds - one or more layer ids of the layer from which every feature is checked for overlap)"] args: ["...layerIds - one or more layer ids of the layer from which every feature is checked for overlap)"]
@ -233,7 +233,7 @@ export class ExtraFunction {
return new Combine([ return new Combine([
ExtraFunction.intro, ExtraFunction.intro,
new List(ExtraFunction.allFuncs.map(func => func._name)), new List(ExtraFunction.allFuncs.map(func => `[${func._name}](#${func._name})`)),
...elems ...elems
]); ]);
} }

View file

@ -37,8 +37,10 @@ export class GeoOperations {
* The features with which 'feature' overlaps, are returned together with their overlap area in m² * The features with which 'feature' overlaps, are returned together with their overlap area in m²
* *
* If 'feature' is a LineString, the features in which this feature is (partly) embedded is returned, the overlap length in meter is given * If 'feature' is a LineString, the features in which this feature is (partly) embedded is returned, the overlap length in meter is given
* If 'feature' is a Polygon, overlapping points and points within the polygon will be returned
* *
* If 'feature' is a point, it will return every feature the point is embedded in. Overlap will be undefined * If 'feature' is a point, it will return every feature the point is embedded in. Overlap will be undefined
*
*/ */
static calculateOverlap(feature: any, otherFeatures: any[]): { feat: any, overlap: number }[] { static calculateOverlap(feature: any, otherFeatures: any[]): { feat: any, overlap: number }[] {

View file

@ -192,11 +192,11 @@ export default class LayerConfig extends WithContextLoader {
} }
this.mapRendering = json.mapRendering this.mapRendering = json.mapRendering
.filter(r => r["icon"] !== undefined || r["label"] !== undefined) .filter(r => r["location"] !== undefined)
.map((r, i) => new PointRenderingConfig(<PointRenderingConfigJson>r, context + ".mapRendering[" + i + "]")) .map((r, i) => new PointRenderingConfig(<PointRenderingConfigJson>r, context + ".mapRendering[" + i + "]"))
this.lineRendering = json.mapRendering this.lineRendering = json.mapRendering
.filter(r => r["icon"] === undefined && r["label"] === undefined) .filter(r => r["location"] === undefined)
.map((r, i) => new LineRenderingConfig(<LineRenderingConfigJson>r, context + ".mapRendering[" + i + "]")) .map((r, i) => new LineRenderingConfig(<LineRenderingConfigJson>r, context + ".mapRendering[" + i + "]"))

View file

@ -40,6 +40,10 @@ export default class PointRenderingConfig extends WithContextLoader {
} }
}) })
if(json.icon === undefined && json.label === undefined){
throw `A point rendering should define at least an icon or a label`
}
if(this.location.size == 0){ if(this.location.size == 0){
throw "A pointRendering should have at least one 'location' to defined where it should be rendered. (At "+context+".location)" throw "A pointRendering should have at least one 'location' to defined where it should be rendered. (At "+context+".location)"
} }

View file

@ -7,11 +7,14 @@ import UserRelatedState from "../Logic/State/UserRelatedState";
import {Utils} from "../Utils"; import {Utils} from "../Utils";
import LanguagePicker from "./LanguagePicker"; import LanguagePicker from "./LanguagePicker";
import IndexText from "./BigComponents/IndexText"; import IndexText from "./BigComponents/IndexText";
import {feature} from "@turf/turf";
import FeaturedMessage from "./BigComponents/FeaturedMessage"; import FeaturedMessage from "./BigComponents/FeaturedMessage";
import {AllKnownLayouts} from "../Customizations/AllKnownLayouts";
export default class AllThemesGui { export default class AllThemesGui {
constructor() { constructor() {
try{
new FixedUiElement("").AttachTo("centermessage") new FixedUiElement("").AttachTo("centermessage")
const state = new UserRelatedState(undefined); const state = new UserRelatedState(undefined);
const intro = new Combine([ const intro = new Combine([
@ -30,5 +33,9 @@ export default class AllThemesGui {
]).SetClass("block m-5 lg:w-3/4 lg:ml-40") ]).SetClass("block m-5 lg:w-3/4 lg:ml-40")
.SetStyle("pointer-events: all;") .SetStyle("pointer-events: all;")
.AttachTo("topleft-tools"); .AttachTo("topleft-tools");
}catch (e) {
new FixedUiElement("Seems like no layers are compiled - check the output of `npm run generate:layeroverview`. Is this visible online? Contact pietervdvn immediately!").SetClass("alert")
.AttachTo("centermessage")
}
} }
} }

View file

@ -38,11 +38,6 @@
"render": "1" "render": "1"
}, },
"mapRendering": [ "mapRendering": [
{
"location": [
"point"
]
},
{ {
"color": "#444444", "color": "#444444",
"width": { "width": {

View file

@ -51,10 +51,37 @@
} }
], ],
"layers": [ "layers": [
{
"id": "raw_inspire_polygons",
"source": {
"geoJson": "https://osm-uk-addresses.russss.dev/inspire/{z}/{x}/{y}.json",
"osmTags": "inspireid~*",
"geoJsonZoomLevel": 18,
"isOsmCache": false
},
"minzoom": 18,
"calculatedTags": [
"_has_address=feat.overlapWith('addresses').length > 0"
],
"#mapRendering": [
{
"width": 2,
"color": {
"render": "#00f",
"mappings": [
{
"if": "_has_address=true",
"then": "#0f0"
}
]
}
}
],
"mapRendering": []
},
{ {
"id": "to_import", "id": "to_import",
"source": { "source": {
"#geoJson": "https://raw.githubusercontent.com/pietervdvn/MapComplete/develop/assets/themes/uk_addresses/islington_small_piece.geojson",
"geoJson": "https://osm-uk-addresses.russss.dev/addresses/{z}/{x}/{y}.json", "geoJson": "https://osm-uk-addresses.russss.dev/addresses/{z}/{x}/{y}.json",
"osmTags": "inspireid~*", "osmTags": "inspireid~*",
"geoJsonZoomLevel": 16, "geoJsonZoomLevel": 16,
@ -73,18 +100,26 @@
{ {
"id": "uk_addresses_embedding_outline", "id": "uk_addresses_embedding_outline",
"render": "An outline embedding this point with an address already exists in OpenStreetMap.<br>This <a href='https://openstreetmap.org/{_embedding_object:id}' target='blank'>object</a> has address <b>{_embedding_object:addr:street} {_embedding_object:addr:housenumber}</b>", "render": "An outline embedding this point with an address already exists in OpenStreetMap.<br>This <a href='https://openstreetmap.org/{_embedding_object:id}' target='blank'>object</a> has address <b>{_embedding_object:addr:street} {_embedding_object:addr:housenumber}</b>",
"mappings": [{
"if": "_embedding_object:id=true",
"then": "The INSPIRE-polygon containing this point has at least one address contained"
},{
"if": "_embedding_object:id=false",
"then": "The INSPIRE-polygon containing this point has <b>no</b> addresses contained"
}],
"condition": "_embedding_object:id~*" "condition": "_embedding_object:id~*"
}, },
{ {
"id": "uk_addresses_import_button", "id": "uk_addresses_import_button",
"render": "{import_button(ref:inspireid=$inspireid, Add this address, ./assets/themes/uk_addresses/housenumber_add.svg)}" "render": "{import_button(addresses,ref:inspireid=$inspireid, Add this address, ./assets/themes/uk_addresses/housenumber_add.svg)}"
} }
], ],
"calculatedTags": [ "calculatedTags": [
"_embedding_object=feat.overlapWith('addresses')[0]?.feat?.properties ?? null", "_embedding_object=feat.overlapWith('addresses')[0]?.feat?.properties ?? null",
"_embedding_object:addr:housenumber=JSON.parse(feat.properties._embedding_object)?.['addr:housenumber']", "_embedding_object:addr:housenumber=JSON.parse(feat.properties._embedding_object)?.['addr:housenumber']",
"_embedding_object:addr:street=JSON.parse(feat.properties._embedding_object)?.['addr:street']", "_embedding_object:addr:street=JSON.parse(feat.properties._embedding_object)?.['addr:street']",
"_embedding_object:id=JSON.parse(feat.properties._embedding_object)?.id" "_embedding_inspire_polygon_has_address=feat.overlapWith('raw_inspire_polygons')[0]?.feat?.properties?._has_address",
"_embedding_object:id=feat.get('_embedding_object')?.id ?? feat.properties._embedding_inspire_polygon_has_address"
], ],
"filter": [ "filter": [
{ {
@ -95,7 +130,12 @@
"osmTags": { "osmTags": {
"and": [ "and": [
"_imported=", "_imported=",
"_embedding_object:id=" {
"or": [
"_embedding_object:id=",
"_embedding_object:id=false"
]
}
] ]
} }
} }
@ -108,7 +148,12 @@
"render": "./assets/themes/uk_addresses/housenumber_unknown.svg", "render": "./assets/themes/uk_addresses/housenumber_unknown.svg",
"mappings": [ "mappings": [
{ {
"if": "_embedding_object:id~*", "if": {
"and": [
"_embedding_object:id~*",
"_embedding_object:id!=false"
]
},
"then": "./assets/themes/uk_addresses/housenumber_unknown_small.svg" "then": "./assets/themes/uk_addresses/housenumber_unknown_small.svg"
}, },
{ {
@ -302,11 +347,6 @@
} }
}, },
"mapRendering": [ "mapRendering": [
{
"location": [
"point"
]
},
{ {
"color": { "color": {
"render": "#ccc" "render": "#ccc"