Merge branch 'develop' into feature/conflation-fix

This commit is contained in:
pietervdvn 2021-12-31 00:55:25 +01:00
commit ba4f4ac685
14 changed files with 113 additions and 23 deletions

View file

@ -16,6 +16,7 @@
+ [left_right_style](#left_right_style) + [left_right_style](#left_right_style)
+ [split_point](#split_point) + [split_point](#split_point)
+ [current_view](#current_view) + [current_view](#current_view)
+ [matchpoint](#matchpoint)
1. [Normal layers](#normal-layers) 1. [Normal layers](#normal-layers)
- [Frequently reused layers](#frequently-reused-layers) - [Frequently reused layers](#frequently-reused-layers)
+ [bicycle_library](#bicycle_library) + [bicycle_library](#bicycle_library)
@ -159,6 +160,7 @@
- [left_right_style](#left_right_style) - [left_right_style](#left_right_style)
- [split_point](#split_point) - [split_point](#split_point)
- [current_view](#current_view) - [current_view](#current_view)
- [matchpoint](#matchpoint)
### gps_location ### gps_location
@ -287,6 +289,19 @@ The icon on the button is the default icon of the layer, but can be customized b
- This layer can **not** be included in a theme. It is solely used by [special renderings](SpecialRenderings.md) showing a minimap with custom data.
### matchpoint
The default rendering for a locationInput which snaps onto another object
[Go to the source code](../assets/layers/matchpoint/matchpoint.json)
- This layer can **not** be included in a theme. It is solely used by [special renderings](SpecialRenderings.md) showing a minimap with custom data. - This layer can **not** be included in a theme. It is solely used by [special renderings](SpecialRenderings.md) showing a minimap with custom data.

View file

@ -18,6 +18,7 @@
+ [_now:date, _now:datetime, _loaded:date, _loaded:_datetime](#_nowdate,-_now:datetime,-_loaded:date,-_loaded:_datetime) + [_now:date, _now:datetime, _loaded:date, _loaded:_datetime](#_nowdate,-_now:datetime,-_loaded:date,-_loaded:_datetime)
+ [_last_edit:contributor, _last_edit:contributor:uid, _last_edit:changeset, _last_edit:timestamp, _version_number, _backend](#_last_editcontributor,-_last_edit:contributor:uid,-_last_edit:changeset,-_last_edit:timestamp,-_version_number,-_backend) + [_last_edit:contributor, _last_edit:contributor:uid, _last_edit:changeset, _last_edit:timestamp, _version_number, _backend](#_last_editcontributor,-_last_edit:contributor:uid,-_last_edit:changeset,-_last_edit:timestamp,-_version_number,-_backend)
+ [sidewalk:left, sidewalk:right, generic_key:left:property, generic_key:right:property](#sidewalkleft,-sidewalk:right,-generic_key:left:property,-generic_key:right:property) + [sidewalk:left, sidewalk:right, generic_key:left:property, generic_key:right:property](#sidewalkleft,-sidewalk:right,-generic_key:left:property,-generic_key:right:property)
+ [_geometry:type](#_geometrytype)
+ [distanceTo](#distanceto) + [distanceTo](#distanceto)
+ [overlapWith](#overlapwith) + [overlapWith](#overlapwith)
+ [intersectionsWith](#intersectionswith) + [intersectionsWith](#intersectionswith)
@ -151,6 +152,16 @@ Rewrites tags from 'generic_key:both:property' as 'generic_key:left:property' an
### _geometry:type
Adds the geometry type as property. This is identical to the GoeJson geometry type and is one of `Point`,`LineString`, `Polygon` and exceptionally `MultiPolygon` or `MultiLineString`
Calculating tags with Javascript Calculating tags with Javascript
---------------------------------- ----------------------------------

View file

@ -42,6 +42,10 @@
* [Example usage of tag_apply](#example-usage-of-tag_apply) * [Example usage of tag_apply](#example-usage-of-tag_apply)
+ [export_as_gpx](#export_as_gpx) + [export_as_gpx](#export_as_gpx)
* [Example usage of export_as_gpx](#example-usage-of-export_as_gpx) * [Example usage of export_as_gpx](#example-usage-of-export_as_gpx)
+ [export_as_geojson](#export_as_geojson)
* [Example usage of export_as_geojson](#example-usage-of-export_as_geojson)
+ [open_in_iD](#open_in_id)
* [Example usage of open_in_iD](#example-usage-of-open_in_id)
+ [clear_location_history](#clear_location_history) + [clear_location_history](#clear_location_history)
* [Example usage of clear_location_history](#example-usage-of-clear_location_history) * [Example usage of clear_location_history](#example-usage-of-clear_location_history)
+ [auto_apply](#auto_apply) + [auto_apply](#auto_apply)
@ -450,6 +454,22 @@ id_of_object_to_apply_this_one | _undefined_ | If specified, applies the the tag
`{export_as_gpx()}` `{export_as_gpx()}`
### export_as_geojson
Exports the selected feature as GeoJson-file
#### Example usage of export_as_geojson
`{export_as_geojson()}`
### open_in_iD
Opens the current view in the iD-editor
#### Example usage of open_in_iD
`{open_in_iD()}`
### clear_location_history ### clear_location_history
A button to remove the travelled track information from the device A button to remove the travelled track information from the device

View file

@ -7,7 +7,6 @@ import Title from "../UI/Base/Title";
import {FixedUiElement} from "../UI/Base/FixedUiElement"; import {FixedUiElement} from "../UI/Base/FixedUiElement";
import LayerConfig from "../Models/ThemeConfig/LayerConfig"; import LayerConfig from "../Models/ThemeConfig/LayerConfig";
import {CountryCoder} from "latlon2country" import {CountryCoder} from "latlon2country"
import ScriptUtils from "../scripts/ScriptUtils";
export class SimpleMetaTagger { export class SimpleMetaTagger {
@ -409,7 +408,21 @@ export default class SimpleMetaTaggers {
feature.properties["_loaded:datetime"] = datetime(freshness); feature.properties["_loaded:datetime"] = datetime(freshness);
return true; return true;
} }
);
public static geometryType = new SimpleMetaTagger(
{
keys:["_geometry:type"],
doc: "Adds the geometry type as property. This is identical to the GoeJson geometry type and is one of `Point`,`LineString`, `Polygon` and exceptionally `MultiPolygon` or `MultiLineString`",
},
(feature, _) => {
const changed = feature.properties["_geometry:type"] === feature.geometry.type;
feature.properties["_geometry:type"] = feature.geometry.type;
return changed
}
) )
public static metatags: SimpleMetaTagger[] = [ public static metatags: SimpleMetaTagger[] = [
SimpleMetaTaggers.latlon, SimpleMetaTaggers.latlon,
SimpleMetaTaggers.layerInfo, SimpleMetaTaggers.layerInfo,
@ -421,7 +434,8 @@ export default class SimpleMetaTaggers {
SimpleMetaTaggers.directionSimplified, SimpleMetaTaggers.directionSimplified,
SimpleMetaTaggers.currentTime, SimpleMetaTaggers.currentTime,
SimpleMetaTaggers.objectMetaInfo, SimpleMetaTaggers.objectMetaInfo,
SimpleMetaTaggers.noBothButLeftRight SimpleMetaTaggers.noBothButLeftRight,
SimpleMetaTaggers.geometryType
]; ];

View file

@ -73,7 +73,13 @@ export default class LayerConfig extends WithContextLoader {
if (json.source.osmTags === undefined) { if (json.source.osmTags === undefined) {
throw "Layer " + this.id + " does not define a osmTags in the source section - these should always be present, even for geojson layers (" + context + ")" throw "Layer " + this.id + " does not define a osmTags in the source section - these should always be present, even for geojson layers (" + context + ")"
}
if(json.id.toLowerCase() !== json.id){
throw `${context}: The id of a layer should be lowercase: ${json.id}`
}
if(json.id.match(/[a-z0-9-_]/) == null){
throw `${context}: The id of a layer should match [a-z0-9-_]*: ${json.id}`
} }
this.maxAgeOfCache = json.source.maxCacheAge ?? 24 * 60 * 60 * 30 this.maxAgeOfCache = json.source.maxCacheAge ?? 24 * 60 * 60 * 30

View file

@ -58,6 +58,12 @@ export default class LayoutConfig {
constructor(json: LayoutConfigJson, official = true, context?: string) { constructor(json: LayoutConfigJson, official = true, context?: string) {
this.official = official; this.official = official;
this.id = json.id; this.id = json.id;
if(json.id.toLowerCase() !== json.id){
throw "The id of a theme should be lowercase: "+json.id
}
if(json.id.match(/[a-z0-9-_]/) == null){
throw "The id of a theme should match [a-z0-9-_]*: "+json.id
}
context = (context ?? "") + "." + this.id; context = (context ?? "") + "." + this.id;
this.maintainer = json.maintainer; this.maintainer = json.maintainer;
this.credits = json.credits; this.credits = json.credits;

View file

@ -350,8 +350,19 @@ export default class ValidatedTextField {
ValidatedTextField.tp( ValidatedTextField.tp(
"email", "email",
"An email adress", "An email adress",
(str) => EmailValidator.validate(str), (str) => {
undefined, if(str.startsWith("mailto:")){
str = str.substring("mailto:".length)
}
return EmailValidator.validate(str);
},
str => {
if(str === undefined){return undefined}
if(str.startsWith("mailto:")){
str = str.substring("mailto:".length)
}
return str;
},
undefined, undefined,
"email"), "email"),
ValidatedTextField.tp( ValidatedTextField.tp(

View file

@ -184,8 +184,15 @@
} }
] ]
}, },
"fill": "no",
"width": { "width": {
"render": "8" "render": "8",
"mappings": [
{
"if": "_geometry:type=Polygon",
"then": "16"
}
]
} }
} }
] ]

View file

@ -543,7 +543,7 @@
"condition": "cuisine=friture" "condition": "cuisine=friture"
}, },
"service:electricity", "service:electricity",
"dog-access" "dog-access","reviews"
], ],
"filter": [ "filter": [
{ {

View file

@ -18,7 +18,7 @@
"layers": [ "layers": [
"defibrillator", "defibrillator",
{ {
"id": "Brugge", "id": "brugge",
"name": "Brugse dataset", "name": "Brugse dataset",
"source": { "source": {
"osmTags": "Brugs volgnummer~*", "osmTags": "Brugs volgnummer~*",

View file

@ -93,7 +93,7 @@
} }
}, },
{ {
"id": "OSM-buildings", "id": "osm-buildings",
"name": "All OSM-buildings", "name": "All OSM-buildings",
"source": { "source": {
"osmTags": "building~*", "osmTags": "building~*",
@ -372,13 +372,13 @@
"builtin": "crab_address", "builtin": "crab_address",
"override": { "override": {
"calculatedTags+": [ "calculatedTags+": [
"_embedded_in=feat.overlapWith('OSM-buildings').filter(b => /* Do not match newly created objects */ b.feat.properties.id.indexOf('-') < 0)[0]?.feat?.properties ?? {}", "_embedded_in=feat.overlapWith('osm-buildings').filter(b => /* Do not match newly created objects */ b.feat.properties.id.indexOf('-') < 0)[0]?.feat?.properties ?? {}",
"_embedding_nr=feat.get('_embedded_in')['addr:housenumber']+(feat.get('_embedded_in')['addr:unit'] ?? '')", "_embedding_nr=feat.get('_embedded_in')['addr:housenumber']+(feat.get('_embedded_in')['addr:unit'] ?? '')",
"_embedding_street=feat.get('_embedded_in')['addr:street']", "_embedding_street=feat.get('_embedded_in')['addr:street']",
"_embedding_id=feat.get('_embedded_in').id", "_embedding_id=feat.get('_embedded_in').id",
"_closeby_addresses=feat.closestn('address',10,undefined,50).map(f => f.feat).filter(addr => addr.properties['addr:street'] == feat.properties['STRAATNM'] && feat.properties['HNRLABEL'] == addr.properties['addr:housenumber'] + (addr.properties['addr:unit']??'') ).length", "_closeby_addresses=feat.closestn('address',10,undefined,50).map(f => f.feat).filter(addr => addr.properties['addr:street'] == feat.properties['STRAATNM'] && feat.properties['HNRLABEL'] == addr.properties['addr:housenumber'] + (addr.properties['addr:unit']??'') ).length",
"_has_identical_closeby_address=feat.get('_closeby_addresses') >= 1 ? 'yes' : 'no'", "_has_identical_closeby_address=feat.get('_closeby_addresses') >= 1 ? 'yes' : 'no'",
"_embedded_in_grb=feat.overlapWith('GRB')[0]?.feat?.properties ?? {}", "_embedded_in_grb=feat.overlapWith('grb')[0]?.feat?.properties ?? {}",
"_embedding_nr_grb=feat.get('_embedded_in_grb')['addr:housenumber']", "_embedding_nr_grb=feat.get('_embedded_in_grb')['addr:housenumber']",
"_embedding_street_grb=feat.get('_embedded_in_grb')['addr:street']" "_embedding_street_grb=feat.get('_embedded_in_grb')['addr:street']"
], ],
@ -452,7 +452,7 @@
}, },
{ {
"id": "import-button", "id": "import-button",
"render": "{import_button(address, addr:street=$STRAATNM; addr:housenumber=$_HNRLABEL,Voeg dit adres als een nieuw adrespunt toe,,OSM-buildings,5)}", "render": "{import_button(address, addr:street=$STRAATNM; addr:housenumber=$_HNRLABEL,Voeg dit adres als een nieuw adrespunt toe,,osm-buildings,5)}",
"condition": { "condition": {
"and": [ "and": [
"_embedding_id!=", "_embedding_id!=",
@ -469,7 +469,7 @@
} }
}, },
{ {
"id": "GRB", "id": "grb",
"description": "Geometry which comes from GRB with tools to import them", "description": "Geometry which comes from GRB with tools to import them",
"source": { "source": {
"osmTags": { "osmTags": {
@ -486,7 +486,7 @@
"name": "GRB geometries", "name": "GRB geometries",
"title": "GRB outline", "title": "GRB outline",
"calculatedTags": [ "calculatedTags": [
"_overlaps_with_buildings=feat.overlapWith('OSM-buildings').filter(f => f.feat.properties.id.indexOf('-') < 0)", "_overlaps_with_buildings=feat.overlapWith('osm-buildings').filter(f => f.feat.properties.id.indexOf('-') < 0)",
"_overlaps_with=feat.get('_overlaps_with_buildings').filter(f => f.overlap > 1 /* square meter */ )[0] ?? ''", "_overlaps_with=feat.get('_overlaps_with_buildings').filter(f => f.overlap > 1 /* square meter */ )[0] ?? ''",
"_overlap_absolute=feat.get('_overlaps_with')?.overlap", "_overlap_absolute=feat.get('_overlaps_with')?.overlap",
"_overlap_percentage=Math.round(100 * feat.get('_overlap_absolute') / feat.get('_surface')) ", "_overlap_percentage=Math.round(100 * feat.get('_overlap_absolute') / feat.get('_surface')) ",
@ -507,7 +507,7 @@
"tagRenderings": [ "tagRenderings": [
{ {
"id": "Import-button", "id": "Import-button",
"render": "{import_way_button(OSM-buildings,building=$building;man_made=$man_made; source:geometry:date=$_grb_date; source:geometry:ref=$_grb_ref; addr:street=$addr:street; addr:housenumber=$addr:housenumber; building:min_level=$_building:min_level, Upload this building to OpenStreetMap,,_is_part_of_building=true,1,_moveable=true)}", "render": "{import_way_button(osm-buildings,building=$building;man_made=$man_made; source:geometry:date=$_grb_date; source:geometry:ref=$_grb_ref; addr:street=$addr:street; addr:housenumber=$addr:housenumber; building:min_level=$_building:min_level, Upload this building to OpenStreetMap,,_is_part_of_building=true,1,_moveable=true)}",
"mappings": [ "mappings": [
{ {
"#": "Hide import button if intersection with other objects are detected", "#": "Hide import button if intersection with other objects are detected",
@ -524,11 +524,11 @@
"addr:housenumber~*" "addr:housenumber~*"
] ]
}, },
"then": "{conflate_button(OSM-buildings,building=$_target_building_type; source:geometry:date=$_grb_date; source:geometry:ref=$_grb_ref; addr:street=$addr:street; addr:housenumber=$addr:housenumber, Replace the geometry in OpenStreetMap and add the address,,_osm_obj:id)}" "then": "{conflate_button(osm-buildings,building=$_target_building_type; source:geometry:date=$_grb_date; source:geometry:ref=$_grb_ref; addr:street=$addr:street; addr:housenumber=$addr:housenumber, Replace the geometry in OpenStreetMap and add the address,,_osm_obj:id)}"
}, },
{ {
"if": "_overlaps_with!=", "if": "_overlaps_with!=",
"then": "{conflate_button(OSM-buildings,building=$_target_building_type; source:geometry:date=$_grb_date; source:geometry:ref=$_grb_ref, Replace the geometry in OpenStreetMap,,_osm_obj:id)}" "then": "{conflate_button(osm-buildings,building=$_target_building_type; source:geometry:date=$_grb_date; source:geometry:ref=$_grb_ref, Replace the geometry in OpenStreetMap,,_osm_obj:id)}"
} }
] ]
}, },

View file

@ -31,7 +31,7 @@
}, },
"layers": [ "layers": [
{ {
"id": "OSM-buildings-fixme", "id": "osm-buildings-fixme",
"name": "OSM-buildings with a fixme", "name": "OSM-buildings with a fixme",
"source": { "source": {
"osmTags": { "osmTags": {

View file

@ -42,7 +42,7 @@
} }
], ],
"calculatedTags": [ "calculatedTags": [
"_overlapping=Number(feat.properties.zoom) >= 14 ? feat.overlapWith('OSM-buildings').map(ff => ff.feat.properties) : undefined", "_overlapping=Number(feat.properties.zoom) >= 14 ? feat.overlapWith('osm-buildings').map(ff => ff.feat.properties) : undefined",
"_applicable=feat.get('_overlapping').filter(p => (p._spelling_is_correct === 'true') && (p._singular_import === 'true')).map(p => p.id)", "_applicable=feat.get('_overlapping').filter(p => (p._spelling_is_correct === 'true') && (p._singular_import === 'true')).map(p => p.id)",
"_applicable_count=feat.get('_applicable')?.length" "_applicable_count=feat.get('_applicable')?.length"
], ],
@ -67,7 +67,7 @@
}, },
{ {
"id": "autoapply", "id": "autoapply",
"render": "{auto_apply(OSM-buildings, _applicable, apply_streetname, Automatically add all missing streetnames on buildings in view)}" "render": "{auto_apply(osm-buildings, _applicable, apply_streetname, Automatically add all missing streetnames on buildings in view)}"
} }
] ]
} }
@ -89,7 +89,7 @@
} }
}, },
{ {
"id": "OSM-buildings", "id": "osm-buildings",
"name": "Alle OSM-gebouwen met een huisnummer en zonder straat", "name": "Alle OSM-gebouwen met een huisnummer en zonder straat",
"source": { "source": {
"osmTags": { "osmTags": {

View file

@ -19,7 +19,7 @@
"layers": [ "layers": [
"street_lamps", "street_lamps",
{ {
"id": "Assen", "id": "assen",
"name": "Dataset Assen", "name": "Dataset Assen",
"source": { "source": {
"osmTags": "Lichtmastnummer~*", "osmTags": "Lichtmastnummer~*",