diff --git a/Logic/FeatureSource/Sources/GeoJsonSource.ts b/Logic/FeatureSource/Sources/GeoJsonSource.ts index a229bb493..4ff718ebe 100644 --- a/Logic/FeatureSource/Sources/GeoJsonSource.ts +++ b/Logic/FeatureSource/Sources/GeoJsonSource.ts @@ -93,7 +93,7 @@ export default class GeoJsonSource implements FeatureSourceForLayer, Tiled { for (const key in props) { if (typeof props[key] !== "string") { // Make sure all the values are string, it crashes stuff otherwise - props[key] = "" + props[key] + props[key] = JSON.stringify(props[key]) } } diff --git a/Logic/MetaTagging.ts b/Logic/MetaTagging.ts index 302762110..13f67c606 100644 --- a/Logic/MetaTagging.ts +++ b/Logic/MetaTagging.ts @@ -104,8 +104,8 @@ export default class MetaTagging { } return atLeastOneFeatureChanged } - public static createFunctionsForFeature(layerId: string, calculatedTags: [string, string, boolean][]): ((feature: any) => boolean)[] { - const functions: ((feature: any) => boolean)[] = []; + public static createFunctionsForFeature(layerId: string, calculatedTags: [string, string, boolean][]): ((feature: any) => void)[] { + const functions: ((feature: any) => any)[] = []; for (const entry of calculatedTags) { const key = entry[0] @@ -115,9 +115,8 @@ export default class MetaTagging { continue; } - const calculateAndAssign: ((feat: any) => boolean) = (feat) => { + const calculateAndAssign: ((feat: any) => any) = (feat) => { try { - let oldValue = isStrict ? feat.properties[key] : undefined let result = new Function("feat", "return " + code + ";")(feat); if (result === "") { result === undefined @@ -128,7 +127,7 @@ export default class MetaTagging { } delete feat.properties[key] feat.properties[key] = result; - return result === oldValue; + return result }catch(e){ if (MetaTagging.errorPrintCount < MetaTagging.stopErrorOutputAt) { console.warn("Could not calculate a " + (isStrict ? "strict " : "") + " calculated tag for key " + key + " defined by " + code + " (in layer" + layerId + ") due to \n" + e + "\n. Are you the theme creator? Doublecheck your code. Note that the metatags might not be stable on new features", e, e.stack) @@ -137,7 +136,7 @@ export default class MetaTagging { console.error("Got ", MetaTagging.stopErrorOutputAt, " errors calculating this metatagging - stopping output now") } } - return false; + return undefined; } } @@ -154,11 +153,10 @@ export default class MetaTagging { configurable: true, enumerable: false, // By setting this as not enumerable, the localTileSaver will _not_ calculate this get: function () { - calculateAndAssign(feature) - return feature.properties[key] + return calculateAndAssign(feature) } }) - return true + return undefined } @@ -167,7 +165,7 @@ export default class MetaTagging { return functions; } - private static retaggingFuncCache = new Map boolean)[]>() + private static retaggingFuncCache = new Map void)[]>() /** * Creates the function which adds all the calculated tags to a feature. Called once per layer @@ -183,7 +181,7 @@ export default class MetaTagging { return undefined; } - let functions :((feature: any) => boolean)[] = MetaTagging.retaggingFuncCache.get(layer.id); + let functions :((feature: any) => void)[] = MetaTagging.retaggingFuncCache.get(layer.id); if (functions === undefined) { functions = MetaTagging.createFunctionsForFeature(layer.id, calculatedTags) MetaTagging.retaggingFuncCache.set(layer.id, functions) diff --git a/Logic/Osm/OsmConnection.ts b/Logic/Osm/OsmConnection.ts index cbf605127..752115c5f 100644 --- a/Logic/Osm/OsmConnection.ts +++ b/Logic/Osm/OsmConnection.ts @@ -218,6 +218,24 @@ export class OsmConnection { }); } + public closeNote(id: number | string): Promise { + return new Promise((ok, error) => { + this.auth.xhr({ + method: 'POST', + path: `/api/0.6/notes/${id}/close` + }, function (err, response) { + console.log("Closing note gave:", err, response) + if (err !== null) { + error(err) + } else { + ok() + } + }) + + }) + + } + private updateAuthObject() { let pwaStandAloneMode = false; try { @@ -260,6 +278,4 @@ export class OsmConnection { }); } - - } \ No newline at end of file diff --git a/Models/TileRange.ts b/Models/TileRange.ts index 9a585a30e..96143b23d 100644 --- a/Models/TileRange.ts +++ b/Models/TileRange.ts @@ -16,7 +16,7 @@ export class Tiles { const result: T[] = [] const total = tileRange.total if (total > 100000) { - throw "Tilerange too big" + throw "Tilerange too big (z is "+tileRange.zoomlevel+")" } for (let x = tileRange.xstart; x <= tileRange.xend; x++) { for (let y = tileRange.ystart; y <= tileRange.yend; y++) { diff --git a/UI/BigComponents/UserBadge.ts b/UI/BigComponents/UserBadge.ts index e85cf6a30..6dfdf7342 100644 --- a/UI/BigComponents/UserBadge.ts +++ b/UI/BigComponents/UserBadge.ts @@ -43,7 +43,7 @@ export default class UserBadge extends Toggle { if (home === undefined) { return; } - state.leafletMap.data.setView([home.lat, home.lon], 16); + state.leafletMap.data?.setView([home.lat, home.lon], 16); }); const linkStyle = "flex items-baseline" diff --git a/UI/OpeningHours/OpeningHours.ts b/UI/OpeningHours/OpeningHours.ts index e1eb5948c..b30b522bd 100644 --- a/UI/OpeningHours/OpeningHours.ts +++ b/UI/OpeningHours/OpeningHours.ts @@ -298,12 +298,16 @@ export class OH { } } - static Parse(rules: string) { + public static simplify(str: string): string{ + return OH.ToString(OH.MergeTimes(OH.Parse(str))) + } + + public static Parse(rules: string) : OpeningHour[] { if (rules === undefined || rules === "") { return [] } - const ohs = [] + const ohs : OpeningHour[] = [] const split = rules.split(";"); diff --git a/UI/Popup/FeatureInfoBox.ts b/UI/Popup/FeatureInfoBox.ts index 56345766c..3b1c6dfa0 100644 --- a/UI/Popup/FeatureInfoBox.ts +++ b/UI/Popup/FeatureInfoBox.ts @@ -44,7 +44,7 @@ export default class FeatureInfoBox extends ScrollableFullScreen { .SetClass("break-words font-bold sm:p-0.5 md:p-1 sm:p-1.5 md:p-2"); const titleIcons = new Combine( layerConfig.titleIcons.map(icon => new TagRenderingAnswer(tags, icon, - "block w-8 h-8 align-baseline box-content sm:p-0.5", "width: 2rem;") + "block w-8 h-8 max-h-8 align-baseline box-content sm:p-0.5", "width: 2rem;") )) .SetClass("flex flex-row flex-wrap pt-0.5 sm:pt-1 items-center mr-2") @@ -193,9 +193,9 @@ export default class FeatureInfoBox extends ScrollableFullScreen { const config_download: TagRenderingConfig = new TagRenderingConfig({render: "{export_as_geojson()}"}, ""); const config_id: TagRenderingConfig = new TagRenderingConfig({render: "{open_in_iD()}"}, ""); - return new Combine([new TagRenderingAnswer(tags, config_all_tags, "all_tags"), - new TagRenderingAnswer(tags, config_download, ""), - new TagRenderingAnswer(tags, config_id, "")]) + return new Combine([new TagRenderingAnswer(tags, config_all_tags, State.state), + new TagRenderingAnswer(tags, config_download, State.state), + new TagRenderingAnswer(tags, config_id, State.state)]) } }) ) diff --git a/UI/SpecialVisualizations.ts b/UI/SpecialVisualizations.ts index 0855f566e..b30821758 100644 --- a/UI/SpecialVisualizations.ts +++ b/UI/SpecialVisualizations.ts @@ -38,6 +38,7 @@ import TagApplyButton from "./Popup/TagApplyButton"; import AutoApplyButton from "./Popup/AutoApplyButton"; import * as left_right_style_json from "../assets/layers/left_right_style/left_right_style.json"; import {OpenIdEditor} from "./BigComponents/CopyrightPanel"; +import Toggle from "./Input/Toggle"; export interface SpecialVisualization { funcName: string, @@ -607,6 +608,39 @@ export default class SpecialVisualizations { Hash.hash.setData(undefined) }) } + }, + { + funcName: "close_note", + docs: "Button to close a note", + args:[ + { + name:"text", + doc: "Text to show on this button", + }, + { + name:"Id-key", + doc: "The property name where the ID of the note to close can be found", + defaultValue: "id" + } + ], + constr: (state, tags, args, guiState) => { + const t = Translations.t.notes; + const closeButton = new SubtleButton( Svg.checkmark_svg(), t.closeNote) + const isClosed = new UIEventSource(false); + closeButton.onClick(() => { + const id = tags.data[args[1] ?? "id"] + if(state.featureSwitchIsTesting.data){ + console.log("Not actually closing note...") + return; + } + state.osmConnection.closeNote(id).then(_ => isClosed.setData(true)) + }) + return new Toggle( + t.isClosed.SetClass("thanks"), + closeButton, + isClosed + ) + } } ] diff --git a/assets/themes/notes/license_info.json b/assets/themes/notes/license_info.json new file mode 100644 index 000000000..79bc48e8e --- /dev/null +++ b/assets/themes/notes/license_info.json @@ -0,0 +1,18 @@ +[ + { + "path": "note.svg", + "license": "CC0", + "authors": [ + "Pieter Vander Vennet" + ], + "sources": [] + }, + { + "path": "resolved.svg", + "license": "CC0", + "authors": [ + "Pieter Vander Vennet" + ], + "sources": [] + } +] \ No newline at end of file diff --git a/assets/themes/notes/note.svg b/assets/themes/notes/note.svg new file mode 100644 index 000000000..369082576 --- /dev/null +++ b/assets/themes/notes/note.svg @@ -0,0 +1,45 @@ + + + + + + + + + diff --git a/assets/themes/notes/notes.json b/assets/themes/notes/notes.json new file mode 100644 index 000000000..beac23cfc --- /dev/null +++ b/assets/themes/notes/notes.json @@ -0,0 +1,93 @@ +{ + "id": "notes", + "language": [ + "en" + ], + "maintainer": "MapComplete", + "startLat": 0, + "startLon": 0, + "startZoom": 0, + "title": "Notes on OpenStreetMap", + "version": "0.1", + "description": "Notes from OpenStreetMap", + "icon": "./assets/themes/notes/resolved.svg", + "clustering": false, + "layers": [ + { + "id": "notes", + "name": { + "en": "OpenStreetMap notes" + }, + "description": "Notes on OpenStreetMap.org", + "source": { + "osmTags": "id~*", + "geoJson": "https://api.openstreetmap.org/api/0.6/notes.json?closed=7&bbox={x_min},{y_min},{x_max},{y_max}", + "geoJsonZoomLevel": 12, + "maxCacheAge": 0 + }, + "minzoom": 10, + "title": { + "render": { + "en": "Note" + }, + "mappings": [{ + "if": "closed_at~*", + "then": { + "en": "Closed note" + } + }] + }, + "calculatedTags": [ + "_first_comment:=feat.get('comments')[0].text", + "_conversation=feat.get('comments').map(c => {if(c.user_url == undefined) {return 'anonymous user, '+c.date;} return c.html+'
'+c.user+'  '+c.date+'
'}).join('')" + ], + "titleIcons": [{ + "render": "" + }], + "tagRenderings": [ + { + "id": "conversation", + "render": "{_conversation}" + }, + { + "id": "date_created", + "render": { + "en": "Opened on {date_created}" + } + }, + { + "id": "close", + "render": "{close_note()}", + "condition": "closed_at=" + } + ], + "mapRendering": [ + { + "location": [ + "point", + "centroid" + ], + "icon": { + "render": "./assets/themes/notes/note.svg", + "mappings": [ + { + "if": "closed_at~*", + "then": "./assets/themes/notes/resolved.svg" + } + ] + }, + + "iconSize": "40,40,bottom" + } + ], + "filter": [{ + "id": "bookcases", + "options": [ + { + "osmTags": "_first_comment~.*bookcase.*", + "question": "Should mention 'bookcase' in the first comment" + }] + }] + } + ] +} \ No newline at end of file diff --git a/assets/themes/notes/resolved.svg b/assets/themes/notes/resolved.svg new file mode 100644 index 000000000..98fcc59db --- /dev/null +++ b/assets/themes/notes/resolved.svg @@ -0,0 +1,46 @@ + + + + + + + + + diff --git a/css/index-tailwind-output.css b/css/index-tailwind-output.css index bcc28e6b2..3895b45e1 100644 --- a/css/index-tailwind-output.css +++ b/css/index-tailwind-output.css @@ -716,18 +716,6 @@ video { left: 0px; } -.bottom-3 { - bottom: 0.75rem; -} - -.left-3 { - left: 0.75rem; -} - -.right-2 { - right: 0.5rem; -} - .left-24 { left: 6rem; } @@ -740,6 +728,18 @@ video { top: 14rem; } +.bottom-3 { + bottom: 0.75rem; +} + +.left-3 { + left: 0.75rem; +} + +.right-2 { + right: 0.5rem; +} + .top-2 { top: 0.5rem; } @@ -800,10 +800,6 @@ video { margin: 2rem; } -.m-11 { - margin: 2.75rem; -} - .m-1 { margin: 0.25rem; } @@ -812,6 +808,10 @@ video { margin: 1.25rem; } +.m-4 { + margin: 1rem; +} + .m-0\.5 { margin: 0.125rem; } @@ -824,10 +824,6 @@ video { margin: 0.75rem; } -.m-4 { - margin: 1rem; -} - .m-2 { margin: 0.5rem; } @@ -1080,6 +1076,10 @@ video { width: 2.75rem; } +.w-6 { + width: 1.5rem; +} + .w-16 { width: 4rem; } @@ -1090,10 +1090,6 @@ video { width: min-content; } -.w-6 { - width: 1.5rem; -} - .w-max { width: -webkit-max-content; width: -moz-max-content; @@ -1565,6 +1561,10 @@ video { text-transform: lowercase; } +.capitalize { + text-transform: capitalize; +} + .italic { font-style: italic; } diff --git a/index.manifest b/index.manifest index 1eb1aec3c..8b8573088 100644 --- a/index.manifest +++ b/index.manifest @@ -62,5 +62,9 @@ "sizes": "513x513", "type": "image/svg" } + ], + "categories": [ + "map", + "navigation" ] } \ No newline at end of file diff --git a/langs/en.json b/langs/en.json index 06d42922b..58776bfe5 100644 --- a/langs/en.json +++ b/langs/en.json @@ -422,5 +422,10 @@ } } } + }, + "notes": { + "isClosed": "This note is resolved", + "closeNote": + "Close this note" } } diff --git a/langs/themes/en.json b/langs/themes/en.json index cd69694b4..3b13d509b 100644 --- a/langs/themes/en.json +++ b/langs/themes/en.json @@ -944,6 +944,18 @@ "shortDescription": "This map shows the nature reserves of Natuurpunt", "title": "The map of Natuurpunt" }, + "notes": { + "layers": { + "0": { + "name": "OpenStreetMap notes", + "tagRenderings": { + "date_created": { + "render": "Opened on {date_created}" + } + } + } + } + }, "observation_towers": { "description": "Publicly accessible towers to enjoy the view", "shortDescription": "Publicly accessible towers to enjoy the view", diff --git a/package.json b/package.json index bdac19110..8f5207c72 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,8 @@ "gittag": "ts-node scripts/printVersion.ts | bash", "lint": "tslint --project . -c tslint.json '**.ts' ", "clean": "rm -rf .cache/ && (find *.html | grep -v \"\\(404\\|index\\|land\\|test\\|preferences\\|customGenerator\\|professional\\|automaton\\|theme\\).html\" | xargs rm) && (ls | grep \"^index_[a-zA-Z_]\\+\\.ts$\" | xargs rm) && (ls | grep \".*.webmanifest$\" | xargs rm)", - "generate:dependency-graph": "node_modules/.bin/depcruise --exclude \"^node_modules\" --output-type dot Logic/State/MapState.ts > dependencies.dot && dot dependencies.dot -T svg -o dependencies.svg && rm dependencies.dot" + "generate:dependency-graph": "node_modules/.bin/depcruise --exclude \"^node_modules\" --output-type dot Logic/State/MapState.ts > dependencies.dot && dot dependencies.dot -T svg -o dependencies.svg && rm dependencies.dot", + "bicycle_rental": "ts-node ./scripts/extractBikeRental.ts" }, "keywords": [ "OpenStreetMap", diff --git a/scripts/extractBikeRental.ts b/scripts/extractBikeRental.ts new file mode 100644 index 000000000..7b6a8f4b8 --- /dev/null +++ b/scripts/extractBikeRental.ts @@ -0,0 +1,211 @@ +import * as fs from "fs"; +import {OH} from "../UI/OpeningHours/OpeningHours"; + + +function extractValue(vs: { __value }[]) { + if(vs === undefined){ + return undefined + } + for (const v of vs) { + if ((v.__value ?? "") === "") { + continue + } + return v.__value; + } + return undefined +} + + +function extract_oh_block (days) : string{ + const oh = [] + for (const day of days.day) { + const abbr = day.name.substr(0,2) + const block = day.time_block[0] + const from = block.time_from.substr(0,5) + const to = block.time_until.substr(0,5) + const by_appointment = block.by_appointment ? " \"by appointment\"" : "" + oh.push(`${abbr} ${from}-${to}${by_appointment}`) + } + return oh.join("; ") +} +function extract_oh(opening_periods){ + const rules = [] + if(opening_periods === undefined){ + return undefined; + } + for (const openingPeriod of opening_periods.opening_period ?? []) { + let rule = extract_oh_block(openingPeriod.days) + if(openingPeriod.name.toLowerCase().indexOf("schoolvakantie") >= 0){ + rule = "SH "+rule + } + rules.push(rule) + } + return OH.simplify( rules.join(";")) +} + +function rewrite(obj, key) { + if (obj[key] === undefined) { + return + } + obj[key] = extractValue(obj[key]["value"]) +} + +const stuff = fs.readFileSync("/home/pietervdvn/Documents/Freelance/ToerismeVlaanderen 2021-09/TeImporteren/allchannels-bike_rental.json", "UTF8") +const data: any[] = JSON.parse(stuff) + +const results: { + geometry: { + type: "Point", + coordinates: [number, number] + }, + type: "Feature", + properties: any + +}[] = [] +const skipped = [] +console.log("[") +for (const item of data) { + const metadata = item["metadata"] + + if (metadata.name === "Jommekeroute") { + continue + } + + const addr = item.location_info?.address + if (addr === undefined) { + skipped.push(item) + continue + } + const toDelete = ["id", "uuid", "update_date", "creation_date", + "deleted", + "aborted", + "partner_id", + "business_product_id", + "winref", + "winref_uuid", + "root_product_type", + "parent" + ] + for (const key of toDelete) { + delete metadata[key] + } + + delete item["meeting_rooms_count"] + delete item["facilities"] + + item.properties = metadata + delete item["metadata"] + + const metadata_values = ["touristic_product_type", "root_product_type"] + for (const key of metadata_values) { + rewrite(metadata, key) + } + + rewrite(item.contact_info, "commercial_name") + + const gl = addr.geolocation + item.coordinates = [gl.lon, gl.lat] + metadata["addr:street"] = addr.street + metadata["addr:housenumber"] = addr.number + metadata["phone"] = item.contact_info["telephone"] ?? item.contact_info["mobile"] + metadata["email"] = item.contact_info["email_address"] + + const links = item.links?.link?.map(l => l.url) ?? [] + metadata["website"] = item.contact_info["website"] ?? links[0] + + delete item["links"] + + delete item.location_info + delete item.contact_info + delete item.promotional_info + + if (metadata["touristic_product_type"] === "Fietsverhuur") { + metadata["amenity"] = "bicycle_rental" + delete metadata["touristic_product_type"] + } else { + console.error("Unkown product type: ", metadata["touristic_product_type"]) + } + + const descriptions = item.descriptions?.description?.map(d => extractValue(d?.text?.value)) ?? [] + delete item.descriptions + metadata["description"] = metadata["description"] ?? descriptions[0] + if (item.price_info?.prices?.free == true) { + metadata.fee = "no" + delete item.price_info + } else if (item.price_info?.prices?.free == false) { + metadata.fee = "yes" + metadata.charge = extractValue(item.price_info?.extra_information?.value) + const methods = item.price_info?.payment_methods?.payment_method + if(methods !== undefined){ + methods.map(v => extractValue(v.value)).forEach(method => { + metadata["payment:" + method.toLowerCase()] = "yes" + }) + } + delete item.price_info + }else if(item.price_info?.prices?.length === 0){ + delete item.price_info + } + + + try{ + + if(item.labels_info?.labels_own?.label[0]?.code === "Billenkar"){ + metadata.rental = "quadricycle" + delete item.labels_info + } + }catch(e){ + + } + delete item["publishing_channels"] + + + try { + metadata["image"] = item.media.file[0].url[0] + } catch (e) { + // No image! + } + delete item.media + + + + const time_info = item.time_info?.time_info_regular + if(time_info?.permantly_open === true){ + metadata.opening_hours = "24/7" + }else{ + metadata.opening_hours = extract_oh(time_info?.opening_periods) + } + delete item.time_info + + + + const properties = {} + for (const key in metadata) { + const v = metadata[key] + if(v === null || v === undefined || v === ""){ + delete metadata[key] + continue + } + properties[key] = v + } + results.push({ + geometry: { + type: "Point", + coordinates: item.coordinates + }, + type: "Feature", + properties + }) + + delete item.coordinates + delete item.properties + console.log(JSON.stringify(item, null, " ") + ",") + +} +console.log("]") +fs.writeFileSync("west-vlaanderen.geojson", JSON.stringify( + { + type: "FeatureCollection", + features: results + } + , null, " " +)) \ No newline at end of file diff --git a/scripts/perProperty.ts b/scripts/perProperty.ts new file mode 100644 index 000000000..953150441 --- /dev/null +++ b/scripts/perProperty.ts @@ -0,0 +1,45 @@ +import * as fs from "fs"; + +function main(args){ + if(args.length < 2){ + console.log("Given a single geojson file, generates the partitions for every found property") + console.log("USAGE: perProperty `file.geojson` `property-key`") + return + } + const path = args[0] + const key = args[1] + + const data= JSON.parse(fs.readFileSync(path, "UTF8")) + const perProperty = new Map() + + console.log("Partitioning",data.features.length, "features") + for (const feature of data.features) { + const v = feature.properties[key] + if(!perProperty.has(v)){ + console.log("Found a new category:", v) + perProperty.set(v, []) + } + perProperty.get(v).push(feature) + } + + const stripped = path.substr(0, path.length - ".geojson".length) + perProperty.forEach((features, v) => { + + fs.writeFileSync(stripped+"."+v.replace(/[^a-zA-Z0-9_]/g, "_")+".geojson", + JSON.stringify({ + type:"FeatureCollection", + features + })) + }) + + +} + +let args = [...process.argv] +args.splice(0, 2) +try { + main(args) +} catch (e) { + console.error("Error building cache:", e) +} +console.log("All done!") \ No newline at end of file diff --git a/test.ts b/test.ts index 2b0b84df9..e4f2d196d 100644 --- a/test.ts +++ b/test.ts @@ -1,152 +1 @@ -import State from "./State"; -import AllKnownLayers from "./Customizations/AllKnownLayers"; -import AvailableBaseLayersImplementation from "./Logic/Actors/AvailableBaseLayersImplementation"; -import AvailableBaseLayers from "./Logic/Actors/AvailableBaseLayers"; -import MinimapImplementation from "./UI/Base/MinimapImplementation"; -import {Utils} from "./Utils"; -import * as grb from "./assets/themes/grb_import/grb.json"; -import ReplaceGeometryAction from "./Logic/Osm/Actions/ReplaceGeometryAction"; -import Minimap from "./UI/Base/Minimap"; -import ShowDataLayer from "./UI/ShowDataLayer/ShowDataLayer"; -import {AllKnownLayouts} from "./Customizations/AllKnownLayouts"; -import {BBox} from "./Logic/BBox"; - -AvailableBaseLayers.implement(new AvailableBaseLayersImplementation()) -MinimapImplementation.initialize() - -async function test() { - - const wayId = "way/323230330"; - const targetFeature = { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 4.483118100000016, - 51.028366499999706 - ], - [ - 4.483135099999986, - 51.028325800000005 - ], - [ - 4.483137700000021, - 51.02831960000019 - ], - [ - 4.4831429000000025, - 51.0283205 - ], - [ - 4.483262199999987, - 51.02834059999982 - ], - [ - 4.483276700000019, - 51.028299999999746 - ], - [ - 4.483342100000037, - 51.02830730000009 - ], - [ - 4.483340700000012, - 51.028331299999934 - ], - [ - 4.483346499999953, - 51.02833189999984 - ], - [ - 4.483290600000001, - 51.028500699999846 - ], - [ - 4.4833335999999635, - 51.02851150000015 - ], - [ - 4.4833433000000475, - 51.028513999999944 - ], - [ - 4.483312899999958, - 51.02857759999998 - ], - [ - 4.483141100000033, - 51.02851780000015 - ], - [ - 4.483193100000022, - 51.028409999999894 - ], - [ - 4.483206100000019, - 51.02838310000014 - ], - [ - 4.483118100000016, - 51.028366499999706 - ] - ] - ] - }, - "id": "https://betadata.grbosm.site/grb?bbox=498980.9206456306,6626173.107985358,499133.7947022009,6626325.98204193/30", - "bbox": { - "maxLat": 51.02857759999998, - "maxLon": 4.483346499999953, - "minLat": 51.028299999999746, - "minLon": 4.483118100000016 - }, - "_lon": 4.483232299999985, - "_lat": 51.02843879999986 - } - - - const layout = AllKnownLayouts.allKnownLayouts.get("grb") - const state = new State(layout) - State.state = state; - const bbox = new BBox( - [[ - 4.482952281832695, - 51.02828527958197 - ], - [ - 4.483400881290436, - 51.028578384406984 - ] - - ]) - const url = `https://www.openstreetmap.org/api/0.6/map.json?bbox=${bbox.minLon},${bbox.minLat},${bbox.maxLon},${bbox.maxLat}` - const data = await Utils.downloadJson(url) - - state.featurePipeline.fullNodeDatabase.handleOsmJson(data, 0) - - - const action = new ReplaceGeometryAction(state, targetFeature, wayId, { - theme: "test" - } - ) - - console.log(">>>>> ", action.GetClosestIds()) - - const map = Minimap.createMiniMap({ - attribution: false, - }) - const preview = await action.getPreview() - new ShowDataLayer({ - layerToShow: AllKnownLayers.sharedLayers.get("conflation"), - features: preview, - leafletMap: map.leafletMap, - zoomToFeatures: true - }) - map - .SetStyle("height: 75vh;") - .AttachTo("maindiv") -} - -test() \ No newline at end of file +console.log("Hello world") \ No newline at end of file