From 7e1c01d3499fc9dcf956f80bcb2dc8957fc4242f Mon Sep 17 00:00:00 2001 From: Wille Marcel Date: Fri, 15 Sep 2017 15:14:33 -0300 Subject: [PATCH 1/2] Link old version changeset id to osmcha #156 --- lib/map.js | 15 ++++++++++++++- public/css/style.css | 6 +++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/lib/map.js b/lib/map.js index a742ddb..04c6765 100644 --- a/lib/map.js +++ b/lib/map.js @@ -854,7 +854,20 @@ function getDiffHTML(diff, ignoreList, header) { tr.appendChild(empty); } - var td = elt('td', { class: propClass }, diff[prop][type]); + if (prop === 'changeset' && type === 'modifiedOld') { + var osmcha_link = elt( + 'a', + { + target: '_blank', + class: 'cmap-changeset-link', + href: '//osmcha.mapbox.com/changesets/' + diff[prop][type] + }, + diff[prop][type] + ); + var td = elt('td', { class: propClass }, osmcha_link); + } else { + var td = elt('td', { class: propClass }, diff[prop][type]); + } tr.appendChild(td); if (type == 'deleted') { diff --git a/public/css/style.css b/public/css/style.css index 4a13d7f..bf5a4ca 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -174,6 +174,10 @@ background: rgba(204, 44, 71, 0.3); } +.cmap-changeset-link { + color: #666; +} + /* Color box ------------------------------------------------------- */ .cmap-hlist-item .cmap-color-box { @@ -365,4 +369,4 @@ .pointer { cursor: pointer; -} \ No newline at end of file +} From 11361a9d5de656e39216019dd8f8362b6a35a5cc Mon Sep 17 00:00:00 2001 From: Wille Marcel Date: Mon, 25 Sep 2017 16:41:05 -0300 Subject: [PATCH 2/2] change indentation to 2 spaces --- .eslintrc | 5 +- lib/config.js | 9 +- lib/getChangeset.js | 104 +-- lib/helpers.js | 44 +- lib/map.js | 1514 +++++++++++++++++++------------------- lib/propsDiff.js | 98 +-- lib/query.js | 74 +- lib/render.js | 126 ++-- lib/sidebar.js | 162 ++-- public/css/mapbox-gl.css | 395 +++++----- rollup.plugin.config.js | 70 +- www/index.js | 56 +- 12 files changed, 1335 insertions(+), 1322 deletions(-) diff --git a/.eslintrc b/.eslintrc index 965bf96..bd8ae62 100644 --- a/.eslintrc +++ b/.eslintrc @@ -5,7 +5,8 @@ ], "rules": { "space-before-function-paren": 0, - "object-curly-spacing": 0 + "object-curly-spacing": 0, + "indent": [2, 2] }, "env": { "browser": true, @@ -20,4 +21,4 @@ "ignore": [ "dist", ] -} \ No newline at end of file +} diff --git a/lib/config.js b/lib/config.js index 5c20dc4..54a3efe 100644 --- a/lib/config.js +++ b/lib/config.js @@ -1,6 +1,7 @@ export const config = { - overpassBase: '//overpass-cfn-production.tilestream.net/api/interpreter', - osmBase: '//www.openstreetmap.org/api/0.6/', - mapboxAccessToken: 'pk.eyJ1IjoicmFzYWd5IiwiYSI6ImNpejVrMjc4eTAwNGczM2thNWozYnJ1OHkifQ.yFRr3Sd39TJiwEguQpIkWQ', - S3_URL: '//s3.amazonaws.com/mapbox/real-changesets/production/' + overpassBase: '//overpass-cfn-production.tilestream.net/api/interpreter', + osmBase: '//www.openstreetmap.org/api/0.6/', + mapboxAccessToken: + 'pk.eyJ1IjoicmFzYWd5IiwiYSI6ImNpejVrMjc4eTAwNGczM2thNWozYnJ1OHkifQ.yFRr3Sd39TJiwEguQpIkWQ', + S3_URL: '//s3.amazonaws.com/mapbox/real-changesets/production/' }; diff --git a/lib/getChangeset.js b/lib/getChangeset.js index aa994cf..6741ed9 100644 --- a/lib/getChangeset.js +++ b/lib/getChangeset.js @@ -4,91 +4,91 @@ import { query } from './query'; import { config } from './config'; export function getChangeset(changesetID, overpassBase = config.overpassBase) { - return query(changesetID).then(changeset => { - var url = config.S3_URL + changesetID + '.json'; - return fetch(url) + return query(changesetID).then(changeset => { + var url = config.S3_URL + changesetID + '.json'; + return fetch(url) .then(r => { - if (r.ok) return r.json(); + if (r.ok) return r.json(); // Fallback to overpass - return Promise.reject(); + return Promise.reject(); }) .then(r => { - var geojson = jsonParser(r); - var featureMap = getFeatureMap(geojson); - var ret = { - geojson: geojson, - featureMap: featureMap, - changeset: changeset - }; - return ret; + var geojson = jsonParser(r); + var featureMap = getFeatureMap(geojson); + var ret = { + geojson: geojson, + featureMap: featureMap, + changeset: changeset + }; + return ret; }) .catch(() => fetchFromOverPass(changesetID, changeset, overpassBase)); - }); + }); } function fetchFromOverPass(changesetID, changeset, overpassBase) { - var data = getDataParam(changeset); - var bbox = getBboxParam(changeset.bbox); - var url = overpassBase + '?data=' + data + '&bbox=' + bbox; + var data = getDataParam(changeset); + var bbox = getBboxParam(changeset.bbox); + var url = overpassBase + '?data=' + data + '&bbox=' + bbox; - return fetch(url, { - 'Response-Type': 'application/osm3s+xml' - }) + return fetch(url, { + 'Response-Type': 'application/osm3s+xml' + }) .then(r => r.text()) .then(response => { - return new Promise((res, rej) => { - adiffParser(response, null, (err, json) => { - if (err) { - return rej({ - msg: 'Failed to parser adiff xml.', - error: err - }); - } - var geojson = jsonParser({ - elements: json[changesetID] - }); - var featureMap = getFeatureMap(geojson); - - var ret = { - geojson: geojson, - featureMap: featureMap, - changeset: changeset - }; - return res(ret); + return new Promise((res, rej) => { + adiffParser(response, null, (err, json) => { + if (err) { + return rej({ + msg: 'Failed to parser adiff xml.', + error: err }); + } + var geojson = jsonParser({ + elements: json[changesetID] + }); + var featureMap = getFeatureMap(geojson); + + var ret = { + geojson: geojson, + featureMap: featureMap, + changeset: changeset + }; + return res(ret); }); + }); }) .catch(err => Promise.reject({ - msg: 'Overpass query failed.', - error: err + msg: 'Overpass query failed.', + error: err }) ); } function getDataParam(c) { - return ( + return ( '[out:xml][adiff:%22' + c.from.toString() + ',%22,%22' + c.to.toString() + '%22];(node(bbox)(changed);way(bbox)(changed);relation(bbox)(changed));out%20meta%20geom(bbox);' - ); + ); } function getBboxParam(bbox) { - return [bbox.left, bbox.bottom, bbox.right, bbox.top].join(','); + return [bbox.left, bbox.bottom, bbox.right, bbox.top].join(','); } function getFeatureMap(geojson) { - var features = geojson.features; - var featureMap = {}; + var features = geojson.features; + var featureMap = {}; - for (var i = 0, len = features.length; i < len; i++) { - var id = features[i].properties.id; - featureMap[id] = featureMap[id] || []; - featureMap[id].push(features[i]); - } + for (var i = 0, len = features.length; i < len; i++) { + var id = features[i].properties.id; + featureMap[id] = featureMap[id] || []; + featureMap[id].push(features[i]); + } - return featureMap; + return featureMap; } diff --git a/lib/helpers.js b/lib/helpers.js index 0a4ce49..ce1bb04 100644 --- a/lib/helpers.js +++ b/lib/helpers.js @@ -5,36 +5,36 @@ import turfBboxPolygon from '@turf/bbox-polygon'; const featureCollection = turfHelpers.featureCollection; export function getBounds(bbox) { - var left = +bbox.left, - right = +bbox.right, - top = +bbox.top, - bottom = +bbox.bottom; + var left = +bbox.left, + right = +bbox.right, + top = +bbox.top, + bottom = +bbox.bottom; - return new mapboxgl.LngLatBounds( + return new mapboxgl.LngLatBounds( new mapboxgl.LngLat(left, bottom), new mapboxgl.LngLat(right, top) ); } export function getBoundingBox(bounds) { - var left = bounds.getWest(), - right = bounds.getEast(), - top = bounds.getNorth(), - bottom = bounds.getSouth(); + var left = bounds.getWest(), + right = bounds.getEast(), + top = bounds.getNorth(), + bottom = bounds.getSouth(); - var padX = 0; - var padY = 0; - if (!(left === -180 && right === 180 && top === 90 && bottom === -90)) { - padX = Math.max((right - left) / 5, 0.0001); - padY = Math.max((top - bottom) / 5, 0.0001); - } + var padX = 0; + var padY = 0; + if (!(left === -180 && right === 180 && top === 90 && bottom === -90)) { + padX = Math.max((right - left) / 5, 0.0001); + padY = Math.max((top - bottom) / 5, 0.0001); + } - var bboxPolygon = turfBboxPolygon([ - left - padX, - bottom - padY, - right + padX, - top + padY - ]); + var bboxPolygon = turfBboxPolygon([ + left - padX, + bottom - padY, + right + padX, + top + padY + ]); - return featureCollection([bboxPolygon]); + return featureCollection([bboxPolygon]); } diff --git a/lib/map.js b/lib/map.js index 04c6765..063ca50 100644 --- a/lib/map.js +++ b/lib/map.js @@ -5,730 +5,730 @@ import { cmap } from './render'; import { propsDiff } from './propsDiff'; export class Map { - constructor() { - this.map = null; - this.queue = []; - this.filterLayers = this.filterLayers.bind(this); - } - filterLayers() { - var layersKey = { - 'added-line': { added: true, ways: true }, - 'added-point-tagged': { added: true, nodes: true }, - 'added-point-untagged': { added: true, nodes: true }, - 'added-relation': { added: true, relations: true }, - 'modified-old-line': { modified: true, ways: true }, - 'modified-old-point-tagged': { modified: true, nodes: true }, - 'modified-old-point-untagged': { modified: true, nodes: true }, - 'modified-old-point-on-way': { modified: true, nodes: true }, - 'modified-new-line': { modified: true, ways: true }, - 'modified-old-relation': { modified: true, relations: true }, - 'modified-new-point-tagged': { modified: true, nodes: true }, - 'modified-new-point-untagged': { modified: true, nodes: true }, - 'modified-new-point-on-way': { modified: true, nodes: true }, - 'modified-new-relation': { modified: true, relations: true }, - 'deleted-line': { deleted: true, ways: true }, - 'deleted-point-tagged': { deleted: true, nodes: true }, - 'deleted-point-untagged': { deleted: true, nodes: true }, - 'deleted-relation': { deleted: true, relations: true } - }; - - var selectedActions = []; - var selectedTypes = []; - document + constructor() { + this.map = null; + this.queue = []; + this.filterLayers = this.filterLayers.bind(this); + } + filterLayers() { + var layersKey = { + 'added-line': { added: true, ways: true }, + 'added-point-tagged': { added: true, nodes: true }, + 'added-point-untagged': { added: true, nodes: true }, + 'added-relation': { added: true, relations: true }, + 'modified-old-line': { modified: true, ways: true }, + 'modified-old-point-tagged': { modified: true, nodes: true }, + 'modified-old-point-untagged': { modified: true, nodes: true }, + 'modified-old-point-on-way': { modified: true, nodes: true }, + 'modified-new-line': { modified: true, ways: true }, + 'modified-old-relation': { modified: true, relations: true }, + 'modified-new-point-tagged': { modified: true, nodes: true }, + 'modified-new-point-untagged': { modified: true, nodes: true }, + 'modified-new-point-on-way': { modified: true, nodes: true }, + 'modified-new-relation': { modified: true, relations: true }, + 'deleted-line': { deleted: true, ways: true }, + 'deleted-point-tagged': { deleted: true, nodes: true }, + 'deleted-point-untagged': { deleted: true, nodes: true }, + 'deleted-relation': { deleted: true, relations: true } + }; + + var selectedActions = []; + var selectedTypes = []; + document .querySelectorAll('.cmap-filter-action-section input:checked') .forEach(function(checkedElement) { - selectedActions.push(checkedElement.value); + selectedActions.push(checkedElement.value); }); - document + document .querySelectorAll('.cmap-filter-type-section input:checked') .forEach(function(checkedElement) { - selectedTypes.push(checkedElement.value); + selectedTypes.push(checkedElement.value); }); - var layers = Object.keys(layersKey); - - layers.forEach(layer => { - var isSelectedAction = selectedActions.reduce(function(accum, action) { - return layersKey[layer][action] || accum; - }, false); - var isSelectedType = selectedTypes.reduce(function(accum, type) { - return layersKey[layer][type] || accum; - }, false); - - if (isSelectedAction && isSelectedType) { - this.map.setLayoutProperty(layer, 'visibility', 'visible'); - } else { - this.map.setLayoutProperty(layer, 'visibility', 'none'); - } - - if (selectedActions.length === 0 || selectedTypes.length === 0) { - this.map.setLayoutProperty('bg-point', 'visibility', 'none'); - this.map.setLayoutProperty('bg-line', 'visibility', 'none'); - } else { - this.map.setLayoutProperty('bg-point', 'visibility', 'visible'); - this.map.setLayoutProperty('bg-line', 'visibility', 'visible'); - } - }); + var layers = Object.keys(layersKey); + + layers.forEach(layer => { + var isSelectedAction = selectedActions.reduce(function(accum, action) { + return layersKey[layer][action] || accum; + }, false); + var isSelectedType = selectedTypes.reduce(function(accum, type) { + return layersKey[layer][type] || accum; + }, false); + + if (isSelectedAction && isSelectedType) { + this.map.setLayoutProperty(layer, 'visibility', 'visible'); + } else { + this.map.setLayoutProperty(layer, 'visibility', 'none'); + } + + if (selectedActions.length === 0 || selectedTypes.length === 0) { + this.map.setLayoutProperty('bg-point', 'visibility', 'none'); + this.map.setLayoutProperty('bg-line', 'visibility', 'none'); + } else { + this.map.setLayoutProperty('bg-point', 'visibility', 'visible'); + this.map.setLayoutProperty('bg-line', 'visibility', 'visible'); + } + }); + } + getMapInstance() { + return this.map; + } + getResult() { + return this.result; + } + remove() { + if (this.map) { + this.map.remove(); + this.mapLoaded = false; + this.map = undefined; } - getMapInstance() { - return this.map; + } + addMapSource(result, bounds) { + if (this.map.getSource('changeset')) { + this.map.getSource('changeset').setData(result.geojson); + } else { + this.map.addSource('changeset', { + type: 'geojson', + data: result.geojson + }); } - getResult() { - return this.result; + + if (this.map.getSource('bbox')) { + this.map.getSource('bbox').setData(getBoundingBox(bounds)); + } else { + this.map.addSource('bbox', { + type: 'geojson', + data: getBoundingBox(bounds) + }); } - remove() { - if (this.map) { - this.map.remove(); - this.mapLoaded = false; - this.map = undefined; + } + addMapLayers() { + this.map.addLayer({ + id: 'bbox-line', + type: 'line', + source: 'bbox', + paint: { + 'line-color': '#A58CF2', + 'line-opacity': 0.75, + 'line-width': 2 + } + }); + + this.map.addLayer({ + id: 'bg-line', + source: 'changeset', + type: 'line', + layout: { + 'line-cap': 'round', + 'line-join': 'round' + }, + paint: { + 'line-color': 'hsl(0, 0%, 15%)', + 'line-width': 12, + 'line-blur': 0.2, + 'line-opacity': { + base: 1.5, + stops: [[12, 0.5], [18, 0.2]] } - } - addMapSource(result, bounds) { - if (this.map.getSource('changeset')) { - this.map.getSource('changeset').setData(result.geojson); - } else { - this.map.addSource('changeset', { - type: 'geojson', - data: result.geojson - }); + }, + filter: ['all', ['==', 'type', 'way']] + }); + + this.map.addLayer({ + id: 'bg-point', + source: 'changeset', + type: 'circle', + paint: { + 'circle-color': 'hsl(0, 0%, 15%)', + 'circle-blur': 0.2, + 'circle-opacity': { + base: 1.5, + stops: [[12, 0.5], [18, 0.2]] + }, + 'circle-radius': { + base: 1.5, + stops: [[10, 12], [16, 10]] } + }, + filter: ['all', ['==', '$type', 'Point']] + }); - if (this.map.getSource('bbox')) { - this.map.getSource('bbox').setData(getBoundingBox(bounds)); - } else { - this.map.addSource('bbox', { - type: 'geojson', - data: getBoundingBox(bounds) - }); + this.map.addLayer({ + id: 'highlight-line', + source: 'changeset', + type: 'line', + layout: { + 'line-join': 'round', + 'line-cap': 'round' + }, + paint: { + 'line-color': 'hsl(0, 0%, 75%)', + 'line-width': { + base: 1, + stops: [[10, 15], [16, 10]] + }, + 'line-opacity': { + base: 1.5, + stops: [[12, 0.75], [18, 0.75]] } - } - addMapLayers() { - this.map.addLayer({ - id: 'bbox-line', - type: 'line', - source: 'bbox', - paint: { - 'line-color': '#A58CF2', - 'line-opacity': 0.75, - 'line-width': 2 - } - }); - - this.map.addLayer({ - id: 'bg-line', - source: 'changeset', - type: 'line', - layout: { - 'line-cap': 'round', - 'line-join': 'round' - }, - paint: { - 'line-color': 'hsl(0, 0%, 15%)', - 'line-width': 12, - 'line-blur': 0.2, - 'line-opacity': { - base: 1.5, - stops: [[12, 0.5], [18, 0.2]] - } - }, - filter: ['all', ['==', 'type', 'way']] - }); - - this.map.addLayer({ - id: 'bg-point', - source: 'changeset', - type: 'circle', - paint: { - 'circle-color': 'hsl(0, 0%, 15%)', - 'circle-blur': 0.2, - 'circle-opacity': { - base: 1.5, - stops: [[12, 0.5], [18, 0.2]] - }, - 'circle-radius': { - base: 1.5, - stops: [[10, 12], [16, 10]] - } - }, - filter: ['all', ['==', '$type', 'Point']] - }); - - this.map.addLayer({ - id: 'highlight-line', - source: 'changeset', - type: 'line', - layout: { - 'line-join': 'round', - 'line-cap': 'round' - }, - paint: { - 'line-color': 'hsl(0, 0%, 75%)', - 'line-width': { - base: 1, - stops: [[10, 15], [16, 10]] - }, - 'line-opacity': { - base: 1.5, - stops: [[12, 0.75], [18, 0.75]] - } - }, - filter: ['all', ['==', 'id', ''], ['==', '$type', 'LineString']] - }); - - this.map.addLayer({ - id: 'highlight-point', - source: 'changeset', - type: 'circle', - paint: { - 'circle-color': 'hsl(0, 0%, 75%)', - 'circle-radius': { - base: 1, - stops: [[10, 10], [16, 11]] - }, - 'circle-opacity': 0.8 - }, - filter: ['all', ['==', 'id', ''], ['==', '$type', 'Point']] - }); + }, + filter: ['all', ['==', 'id', ''], ['==', '$type', 'LineString']] + }); + + this.map.addLayer({ + id: 'highlight-point', + source: 'changeset', + type: 'circle', + paint: { + 'circle-color': 'hsl(0, 0%, 75%)', + 'circle-radius': { + base: 1, + stops: [[10, 10], [16, 11]] + }, + 'circle-opacity': 0.8 + }, + filter: ['all', ['==', 'id', ''], ['==', '$type', 'Point']] + }); // Relations - this.map.addLayer({ - id: 'deleted-relation', - source: 'changeset', - type: 'line', - paint: { - 'line-color': '#CC2C47', - 'line-width': { - base: 1, - stops: [[8, 1.5], [12, 1.5]] - }, - 'line-dasharray': [0.1, 0.1], - 'line-opacity': 0.8 - }, - filter: [ - 'all', + this.map.addLayer({ + id: 'deleted-relation', + source: 'changeset', + type: 'line', + paint: { + 'line-color': '#CC2C47', + 'line-width': { + base: 1, + stops: [[8, 1.5], [12, 1.5]] + }, + 'line-dasharray': [0.1, 0.1], + 'line-opacity': 0.8 + }, + filter: [ + 'all', ['==', 'type', 'relation'], ['==', 'changeType', 'deletedNew'] - ] - }); - - this.map.addLayer({ - id: 'modified-old-relation', - source: 'changeset', - type: 'line', - layout: { - 'line-join': 'round', - 'line-cap': 'round' - }, - paint: { - 'line-color': '#DB950A', - 'line-width': { - base: 1, - stops: [[8, 1.75], [12, 1.75]] - }, - 'line-blur': 0.25, - 'line-opacity': 0.8 - }, - filter: [ - 'all', + ] + }); + + this.map.addLayer({ + id: 'modified-old-relation', + source: 'changeset', + type: 'line', + layout: { + 'line-join': 'round', + 'line-cap': 'round' + }, + paint: { + 'line-color': '#DB950A', + 'line-width': { + base: 1, + stops: [[8, 1.75], [12, 1.75]] + }, + 'line-blur': 0.25, + 'line-opacity': 0.8 + }, + filter: [ + 'all', ['==', 'type', 'relation'], ['==', 'changeType', 'modifiedOld'] - ] - }); - - this.map.addLayer({ - id: 'modified-new-relation', - source: 'changeset', - type: 'line', - layout: { - 'line-join': 'round', - 'line-cap': 'round' - }, - paint: { - 'line-color': '#E8E845', - 'line-width': { - base: 1, - stops: [[8, 1.25], [12, 1.25]] - }, - 'line-opacity': 0.8 - }, - filter: [ - 'all', + ] + }); + + this.map.addLayer({ + id: 'modified-new-relation', + source: 'changeset', + type: 'line', + layout: { + 'line-join': 'round', + 'line-cap': 'round' + }, + paint: { + 'line-color': '#E8E845', + 'line-width': { + base: 1, + stops: [[8, 1.25], [12, 1.25]] + }, + 'line-opacity': 0.8 + }, + filter: [ + 'all', ['==', 'type', 'relation'], ['==', 'changeType', 'modifiedNew'] - ] - }); - - this.map.addLayer({ - id: 'added-relation', - source: 'changeset', - type: 'line', - interactive: true, - layout: { - 'line-join': 'round', - 'line-cap': 'round' - }, - paint: { - 'line-color': '#39DBC0', - 'line-width': { - base: 1, - stops: [[8, 1], [12, 1]] - }, - 'line-opacity': 0.8 - }, - filter: ['all', ['==', 'type', 'relation'], ['==', 'changeType', 'added']] - }); - - this.map.addLayer({ - id: 'deleted-line', - source: 'changeset', - type: 'line', - paint: { - 'line-color': '#CC2C47', - 'line-width': { - base: 1, - stops: [[8, 3], [12, 5]] - }, - 'line-dasharray': [0.1, 0.25], - 'line-opacity': 0.8 - }, - filter: ['all', ['==', 'type', 'way'], ['==', 'changeType', 'deletedNew']] - }); - - this.map.addLayer({ - id: 'modified-old-point-on-way', - source: 'changeset', - type: 'circle', - paint: { - 'circle-color': '#DB950A', - 'circle-opacity': { - base: 1.5, - stops: [[10, 0.25], [14, 0.5]] - }, - 'circle-blur': 0.25, - 'circle-radius': { - base: 1.5, - stops: [[10, 2.5], [16, 3.5]] - } - }, - filter: [ - 'all', + ] + }); + + this.map.addLayer({ + id: 'added-relation', + source: 'changeset', + type: 'line', + interactive: true, + layout: { + 'line-join': 'round', + 'line-cap': 'round' + }, + paint: { + 'line-color': '#39DBC0', + 'line-width': { + base: 1, + stops: [[8, 1], [12, 1]] + }, + 'line-opacity': 0.8 + }, + filter: ['all', ['==', 'type', 'relation'], ['==', 'changeType', 'added']] + }); + + this.map.addLayer({ + id: 'deleted-line', + source: 'changeset', + type: 'line', + paint: { + 'line-color': '#CC2C47', + 'line-width': { + base: 1, + stops: [[8, 3], [12, 5]] + }, + 'line-dasharray': [0.1, 0.25], + 'line-opacity': 0.8 + }, + filter: ['all', ['==', 'type', 'way'], ['==', 'changeType', 'deletedNew']] + }); + + this.map.addLayer({ + id: 'modified-old-point-on-way', + source: 'changeset', + type: 'circle', + paint: { + 'circle-color': '#DB950A', + 'circle-opacity': { + base: 1.5, + stops: [[10, 0.25], [14, 0.5]] + }, + 'circle-blur': 0.25, + 'circle-radius': { + base: 1.5, + stops: [[10, 2.5], [16, 3.5]] + } + }, + filter: [ + 'all', ['==', '$type', 'LineString'], ['==', 'changeType', 'modifiedOld'] - ] - }); - - this.map.addLayer({ - id: 'modified-old-line', - source: 'changeset', - type: 'line', - layout: { - 'line-join': 'round', - 'line-cap': 'round' - }, - paint: { - 'line-color': '#DB950A', - 'line-width': { - base: 1, - stops: [[8, 3], [12, 6]] - }, - 'line-blur': { - base: 1, - stops: [[8, 0.25], [12, 0.5]] - }, - 'line-opacity': 0.6 - }, - filter: [ - 'all', + ] + }); + + this.map.addLayer({ + id: 'modified-old-line', + source: 'changeset', + type: 'line', + layout: { + 'line-join': 'round', + 'line-cap': 'round' + }, + paint: { + 'line-color': '#DB950A', + 'line-width': { + base: 1, + stops: [[8, 3], [12, 6]] + }, + 'line-blur': { + base: 1, + stops: [[8, 0.25], [12, 0.5]] + }, + 'line-opacity': 0.6 + }, + filter: [ + 'all', ['==', 'type', 'way'], ['==', 'changeType', 'modifiedOld'] - ] - }); - - this.map.addLayer({ - id: 'modified-new-point-on-way', - source: 'changeset', - type: 'circle', - paint: { - 'circle-color': '#E8E845', - 'circle-opacity': { - base: 1.5, - stops: [[10, 0.25], [14, 0.25]] - }, - 'circle-radius': { - base: 1.5, - stops: [[10, 1.25], [16, 2.25]] - } - }, - filter: [ - 'all', + ] + }); + + this.map.addLayer({ + id: 'modified-new-point-on-way', + source: 'changeset', + type: 'circle', + paint: { + 'circle-color': '#E8E845', + 'circle-opacity': { + base: 1.5, + stops: [[10, 0.25], [14, 0.25]] + }, + 'circle-radius': { + base: 1.5, + stops: [[10, 1.25], [16, 2.25]] + } + }, + filter: [ + 'all', ['==', '$type', 'LineString'], ['==', 'changeType', 'modifiedNew'] - ] - }); - - this.map.addLayer({ - id: 'modified-new-line', - source: 'changeset', - type: 'line', - layout: { - 'line-join': 'round', - 'line-cap': 'round' - }, - paint: { - 'line-color': '#E8E845', - 'line-width': { - base: 1, - stops: [[8, 1], [12, 2]] - }, - 'line-opacity': 0.6 - }, - filter: [ - 'all', + ] + }); + + this.map.addLayer({ + id: 'modified-new-line', + source: 'changeset', + type: 'line', + layout: { + 'line-join': 'round', + 'line-cap': 'round' + }, + paint: { + 'line-color': '#E8E845', + 'line-width': { + base: 1, + stops: [[8, 1], [12, 2]] + }, + 'line-opacity': 0.6 + }, + filter: [ + 'all', ['==', 'type', 'way'], ['==', 'changeType', 'modifiedNew'] - ] - }); - - this.map.addLayer({ - id: 'added-line', - source: 'changeset', - type: 'line', - interactive: true, - layout: { - 'line-join': 'round', - 'line-cap': 'round' - }, - paint: { - 'line-color': '#39DBC0', - 'line-width': { - base: 1, - stops: [[8, 1], [12, 1.5]] - }, - 'line-opacity': 0.8 - }, - filter: ['all', ['==', 'type', 'way'], ['==', 'changeType', 'added']] - }); - - this.map.addLayer({ - id: 'deleted-point-untagged', - source: 'changeset', - type: 'circle', - paint: { - 'circle-color': '#CC2C47', - 'circle-radius': { - base: 1.5, - stops: [[10, 2], [16, 3]] - }, - 'circle-opacity': { - base: 1.5, - stops: [[10, 0.25], [14, 0.5]] - } - }, - filter: [ - 'all', + ] + }); + + this.map.addLayer({ + id: 'added-line', + source: 'changeset', + type: 'line', + interactive: true, + layout: { + 'line-join': 'round', + 'line-cap': 'round' + }, + paint: { + 'line-color': '#39DBC0', + 'line-width': { + base: 1, + stops: [[8, 1], [12, 1.5]] + }, + 'line-opacity': 0.8 + }, + filter: ['all', ['==', 'type', 'way'], ['==', 'changeType', 'added']] + }); + + this.map.addLayer({ + id: 'deleted-point-untagged', + source: 'changeset', + type: 'circle', + paint: { + 'circle-color': '#CC2C47', + 'circle-radius': { + base: 1.5, + stops: [[10, 2], [16, 3]] + }, + 'circle-opacity': { + base: 1.5, + stops: [[10, 0.25], [14, 0.5]] + } + }, + filter: [ + 'all', ['==', 'changeType', 'deletedOld'], ['any', ['==', 'tagsCount', 0], ['==', '$type', 'LineString']] - ] - }); - - this.map.addLayer({ - id: 'modified-old-point-untagged', - source: 'changeset', - type: 'circle', - paint: { - 'circle-color': '#DB950A', - 'circle-opacity': { - base: 1.5, - stops: [[10, 0.25], [14, 0.5]] - }, - 'circle-radius': { - base: 1.5, - stops: [[10, 1.75], [16, 3]] - }, - 'circle-stroke-width': 1, - 'circle-stroke-opacity': 0.9, - 'circle-stroke-color': '#DB950A' - }, - filter: [ - 'all', + ] + }); + + this.map.addLayer({ + id: 'modified-old-point-untagged', + source: 'changeset', + type: 'circle', + paint: { + 'circle-color': '#DB950A', + 'circle-opacity': { + base: 1.5, + stops: [[10, 0.25], [14, 0.5]] + }, + 'circle-radius': { + base: 1.5, + stops: [[10, 1.75], [16, 3]] + }, + 'circle-stroke-width': 1, + 'circle-stroke-opacity': 0.9, + 'circle-stroke-color': '#DB950A' + }, + filter: [ + 'all', ['==', 'type', 'node'], ['==', 'changeType', 'modifiedOld'], ['==', 'tagsCount', 0] - ] - }); - - this.map.addLayer({ - id: 'modified-new-point-untagged', - source: 'changeset', - type: 'circle', - paint: { - 'circle-color': '#E8E845', - 'circle-opacity': { - base: 1.5, - stops: [[10, 0.25], [14, 0.5]] - }, - 'circle-radius': { - base: 1.5, - stops: [[10, 0.75], [16, 2]] - }, - 'circle-stroke-width': 1, - 'circle-stroke-opacity': 0.9, - 'circle-stroke-color': '#E8E845' - }, - filter: [ - 'all', + ] + }); + + this.map.addLayer({ + id: 'modified-new-point-untagged', + source: 'changeset', + type: 'circle', + paint: { + 'circle-color': '#E8E845', + 'circle-opacity': { + base: 1.5, + stops: [[10, 0.25], [14, 0.5]] + }, + 'circle-radius': { + base: 1.5, + stops: [[10, 0.75], [16, 2]] + }, + 'circle-stroke-width': 1, + 'circle-stroke-opacity': 0.9, + 'circle-stroke-color': '#E8E845' + }, + filter: [ + 'all', ['==', 'type', 'node'], ['==', 'changeType', 'modifiedNew'], ['==', 'tagsCount', 0] - ] - }); - - this.map.addLayer({ - id: 'added-point-untagged', - source: 'changeset', - type: 'circle', - paint: { - 'circle-color': '#39DBC0', - 'circle-opacity': { - base: 1.5, - stops: [[10, 0.3], [14, 0.75]] - }, - 'circle-radius': { - base: 1.5, - stops: [[10, 1.25], [16, 1.9]] - } - }, - filter: [ - 'all', + ] + }); + + this.map.addLayer({ + id: 'added-point-untagged', + source: 'changeset', + type: 'circle', + paint: { + 'circle-color': '#39DBC0', + 'circle-opacity': { + base: 1.5, + stops: [[10, 0.3], [14, 0.75]] + }, + 'circle-radius': { + base: 1.5, + stops: [[10, 1.25], [16, 1.9]] + } + }, + filter: [ + 'all', ['==', 'type', 'node'], ['==', 'changeType', 'added'], ['==', 'tagsCount', 0] - ] - }); - - this.map.addLayer({ - id: 'deleted-point-tagged', - source: 'changeset', - type: 'circle', - paint: { - 'circle-color': '#CC2C47', - 'circle-radius': { - base: 1.5, - stops: [[10, 4], [16, 7]] - }, - 'circle-opacity': { - base: 1.5, - stops: [[10, 0.25], [14, 0.5]] - }, - 'circle-stroke-width': 1, - 'circle-stroke-opacity': 0.75, - 'circle-stroke-color': '#CC2C47' - }, - filter: [ - 'all', + ] + }); + + this.map.addLayer({ + id: 'deleted-point-tagged', + source: 'changeset', + type: 'circle', + paint: { + 'circle-color': '#CC2C47', + 'circle-radius': { + base: 1.5, + stops: [[10, 4], [16, 7]] + }, + 'circle-opacity': { + base: 1.5, + stops: [[10, 0.25], [14, 0.5]] + }, + 'circle-stroke-width': 1, + 'circle-stroke-opacity': 0.75, + 'circle-stroke-color': '#CC2C47' + }, + filter: [ + 'all', ['==', 'type', 'node'], ['==', 'changeType', 'deletedOld'], ['!=', 'tagsCount', 0] - ] - }); - - this.map.addLayer({ - id: 'modified-old-point-tagged', - source: 'changeset', - type: 'circle', - paint: { - 'circle-color': '#DB950A', - 'circle-opacity': { - base: 1.5, - stops: [[10, 0.25], [14, 0.75]] - }, - 'circle-radius': { - base: 1.5, - stops: [[10, 2.5], [16, 9]] - }, - 'circle-stroke-width': 1, - 'circle-stroke-opacity': 0.9, - 'circle-stroke-color': '#DB950A' - }, - filter: [ - 'all', + ] + }); + + this.map.addLayer({ + id: 'modified-old-point-tagged', + source: 'changeset', + type: 'circle', + paint: { + 'circle-color': '#DB950A', + 'circle-opacity': { + base: 1.5, + stops: [[10, 0.25], [14, 0.75]] + }, + 'circle-radius': { + base: 1.5, + stops: [[10, 2.5], [16, 9]] + }, + 'circle-stroke-width': 1, + 'circle-stroke-opacity': 0.9, + 'circle-stroke-color': '#DB950A' + }, + filter: [ + 'all', ['==', 'type', 'node'], ['==', 'changeType', 'modifiedOld'], ['!=', 'tagsCount', 0] - ] - }); - - this.map.addLayer({ - id: 'modified-new-point-tagged', - source: 'changeset', - type: 'circle', - paint: { - 'circle-color': '#E8E845', - 'circle-opacity': { - base: 1.5, - stops: [[10, 0.25], [14, 0.75]] - }, - 'circle-radius': { - base: 1.5, - stops: [[10, 2], [16, 7]] - }, - 'circle-stroke-width': 1, - 'circle-stroke-opacity': 0.9, - 'circle-stroke-color': '#E8E845' - }, - filter: [ - 'all', + ] + }); + + this.map.addLayer({ + id: 'modified-new-point-tagged', + source: 'changeset', + type: 'circle', + paint: { + 'circle-color': '#E8E845', + 'circle-opacity': { + base: 1.5, + stops: [[10, 0.25], [14, 0.75]] + }, + 'circle-radius': { + base: 1.5, + stops: [[10, 2], [16, 7]] + }, + 'circle-stroke-width': 1, + 'circle-stroke-opacity': 0.9, + 'circle-stroke-color': '#E8E845' + }, + filter: [ + 'all', ['==', 'type', 'node'], ['==', 'changeType', 'modifiedNew'], ['!=', 'tagsCount', 0] - ] - }); - - this.map.addLayer({ - id: 'added-point-tagged', - source: 'changeset', - type: 'circle', - paint: { - 'circle-color': '#39DBC0', - 'circle-opacity': { - base: 1.5, - stops: [[10, 0.3], [14, 0.75]] - }, - 'circle-radius': { - base: 1.5, - stops: [[10, 1], [16, 5]] - }, - 'circle-stroke-width': 1, - 'circle-stroke-opacity': 0.9, - 'circle-stroke-color': '#39DBC0' - }, - filter: [ - 'all', + ] + }); + + this.map.addLayer({ + id: 'added-point-tagged', + source: 'changeset', + type: 'circle', + paint: { + 'circle-color': '#39DBC0', + 'circle-opacity': { + base: 1.5, + stops: [[10, 0.3], [14, 0.75]] + }, + 'circle-radius': { + base: 1.5, + stops: [[10, 1], [16, 5]] + }, + 'circle-stroke-width': 1, + 'circle-stroke-opacity': 0.9, + 'circle-stroke-color': '#39DBC0' + }, + filter: [ + 'all', ['==', 'type', 'node'], ['==', 'changeType', 'added'], ['!=', 'tagsCount', 0] - ] - }); - } - - renderMap(baseLayer, result) { - var bounds = getBounds(result.changeset.bbox); - this.result = result; - if (this.map) { - if (!this.mapLoaded) { - this.queue.push([result, bounds]); // TOFIX use variable instead of array - return; - } - this.addMapSource(result, bounds); - this.map.fitBounds(bounds, { linear: true, padding: 200 }); + ] + }); + } + + renderMap(baseLayer, result) { + var bounds = getBounds(result.changeset.bbox); + this.result = result; + if (this.map) { + if (!this.mapLoaded) { + this.queue.push([result, bounds]); // TOFIX use variable instead of array + return; + } + this.addMapSource(result, bounds); + this.map.fitBounds(bounds, { linear: true, padding: 200 }); // why not re attach on('click') // if the map is still mounted // it will automatically take the latest // result thanks to this.result - return; - } - - this.map = new mapboxgl.Map({ - container: document.querySelector('.cmap-map'), - style: baseLayer || 'mapbox://styles/rasagy/cizp6lsah00ct2snu6gi3p16q', - center: bounds.getCenter(), - zoom: 14, - dragRotate: false, - touchZoomRotate: false - }); - - this.map.on('load', () => { - this.mapLoaded = true; - if (this.queue.length > 0) { - const index = this.queue.length - 1; - result = this.queue[index][0]; - bounds = this.queue[index][1]; - this.queue = []; - } - this.map.fitBounds(bounds, { linear: true, padding: 200 }); - this.addMapSource(result, bounds); - this.addMapLayers(); - cmap.emit('load'); - }); - - this.map.on('click', e => { - var x1y1 = [e.point.x - 5, e.point.y - 5]; - var x2y2 = [e.point.x + 5, e.point.y + 5]; - var features = this.map.queryRenderedFeatures([x1y1, x2y2], { - layers: [ - 'added-line', - 'added-point-tagged', - 'modified-old-line', - 'modified-old-point-tagged', - 'modified-old-point-untagged', - 'modified-new-line', - 'modified-new-point-tagged', - 'modified-new-point-untagged', - 'deleted-line', - 'deleted-point-tagged', - 'added-relation', - 'modified-old-relation', - 'modified-new-relation', - 'deleted-relation' - ] - }); - - if (features.length) { - this.selectFeature(features[0]); - } else { - this.clearFeature(); - } - }); - } - selectFeature(feature) { - var featureMap = this.result.featureMap; - var featureId = feature.properties.id; - var osmType = feature.properties.type; - - this.highlightFeature(featureId); - displayDiff(featureId, featureMap); - cmap.emit('featureChange', osmType, featureId); - } - highlightFeature(featureId) { - this.map.setFilter('highlight-line', ['==', 'id', featureId]); - this.map.setFilter('highlight-point', ['==', 'id', featureId]); - } - clearHighlight() { - this.map.setFilter('highlight-line', ['==', 'id', '']); - this.map.setFilter('highlight-point', ['==', 'id', '']); - } - clearFeature() { - this.clearHighlight(); - clearDiff(); - cmap.emit('featureChange', null, null); + return; } + + this.map = new mapboxgl.Map({ + container: document.querySelector('.cmap-map'), + style: baseLayer || 'mapbox://styles/rasagy/cizp6lsah00ct2snu6gi3p16q', + center: bounds.getCenter(), + zoom: 14, + dragRotate: false, + touchZoomRotate: false + }); + + this.map.on('load', () => { + this.mapLoaded = true; + if (this.queue.length > 0) { + const index = this.queue.length - 1; + result = this.queue[index][0]; + bounds = this.queue[index][1]; + this.queue = []; + } + this.map.fitBounds(bounds, { linear: true, padding: 200 }); + this.addMapSource(result, bounds); + this.addMapLayers(); + cmap.emit('load'); + }); + + this.map.on('click', e => { + var x1y1 = [e.point.x - 5, e.point.y - 5]; + var x2y2 = [e.point.x + 5, e.point.y + 5]; + var features = this.map.queryRenderedFeatures([x1y1, x2y2], { + layers: [ + 'added-line', + 'added-point-tagged', + 'modified-old-line', + 'modified-old-point-tagged', + 'modified-old-point-untagged', + 'modified-new-line', + 'modified-new-point-tagged', + 'modified-new-point-untagged', + 'deleted-line', + 'deleted-point-tagged', + 'added-relation', + 'modified-old-relation', + 'modified-new-relation', + 'deleted-relation' + ] + }); + + if (features.length) { + this.selectFeature(features[0]); + } else { + this.clearFeature(); + } + }); + } + selectFeature(feature) { + var featureMap = this.result.featureMap; + var featureId = feature.properties.id; + var osmType = feature.properties.type; + + this.highlightFeature(featureId); + displayDiff(featureId, featureMap); + cmap.emit('featureChange', osmType, featureId); + } + highlightFeature(featureId) { + this.map.setFilter('highlight-line', ['==', 'id', featureId]); + this.map.setFilter('highlight-point', ['==', 'id', featureId]); + } + clearHighlight() { + this.map.setFilter('highlight-line', ['==', 'id', '']); + this.map.setFilter('highlight-point', ['==', 'id', '']); + } + clearFeature() { + this.clearHighlight(); + clearDiff(); + cmap.emit('featureChange', null, null); + } } //Calculates the difference in the selected features function displayDiff(id, featureMap) { - var featuresWithId = featureMap[id]; - var metadataProps = featuresWithId.map(function(f) { - var props = Object.assign({}, f.properties); - delete props.tags; - delete props.tagsCount; - delete props.relations; - delete props.action; - return props; - }); - var tagProps = featuresWithId.map(function(f) { - var props = Object.assign({}, f.properties.tags); - props.changeType = f.properties.changeType; - return props; - }); + var featuresWithId = featureMap[id]; + var metadataProps = featuresWithId.map(function(f) { + var props = Object.assign({}, f.properties); + delete props.tags; + delete props.tagsCount; + delete props.relations; + delete props.action; + return props; + }); + var tagProps = featuresWithId.map(function(f) { + var props = Object.assign({}, f.properties.tags); + props.changeType = f.properties.changeType; + return props; + }); // Sets headers for two tables - var type = featuresWithId[0].properties.type; - var metadataHeader = elt( + var type = featuresWithId[0].properties.type; + var metadataHeader = elt( 'div', {}, elt('span', { class: 'cmap-inline-block' }, type.toUpperCase() + ': ' + id), @@ -740,11 +740,11 @@ function displayDiff(id, featureMap) { {}, elt( 'a', - { - target: '_blank', - class: 'cmap-hlist-item cmap-pointer cmap-noselect', - href: '//www.openstreetmap.org/' + type + '/' + id + '/history' - }, + { + target: '_blank', + class: 'cmap-hlist-item cmap-pointer cmap-noselect', + href: '//www.openstreetmap.org/' + type + '/' + id + '/history' + }, 'OSM' ) ), @@ -753,64 +753,64 @@ function displayDiff(id, featureMap) { {}, elt( 'a', - { - target: '_blank', - class: 'cmap-hlist-item cmap-pointer cmap-noselect', - href: '//osmlab.github.io/osm-deep-history/#/' + type + '/' + id - }, + { + target: '_blank', + class: 'cmap-hlist-item cmap-pointer cmap-noselect', + href: '//osmlab.github.io/osm-deep-history/#/' + type + '/' + id + }, 'Deep History' ) ) ) ); - var metadataHTML = getDiffHTML( + var metadataHTML = getDiffHTML( propsDiff(metadataProps), ['id', 'type', 'changeType'], metadataHeader ); - var tagHeader = elt( + var tagHeader = elt( 'span', { class: 'cmap-inline-block' }, 'Tag details'.toUpperCase() ); - var tagHTML = getDiffHTML( + var tagHTML = getDiffHTML( propsDiff(tagProps), ['id', 'changeType'], tagHeader ); - document.querySelector('.cmap-diff').style.display = 'block'; + document.querySelector('.cmap-diff').style.display = 'block'; - document.querySelector('.cmap-diff-metadata').innerHTML = ''; - document.querySelector('.cmap-diff-metadata').appendChild(metadataHTML); - document.querySelector('.cmap-diff-metadata').style.display = 'block'; + document.querySelector('.cmap-diff-metadata').innerHTML = ''; + document.querySelector('.cmap-diff-metadata').appendChild(metadataHTML); + document.querySelector('.cmap-diff-metadata').style.display = 'block'; - document.querySelector('.cmap-diff-tags').innerHTML = ''; - document.querySelector('.cmap-diff-tags').appendChild(tagHTML); - document.querySelector('.cmap-diff-tags').style.display = 'block'; + document.querySelector('.cmap-diff-tags').innerHTML = ''; + document.querySelector('.cmap-diff-tags').appendChild(tagHTML); + document.querySelector('.cmap-diff-tags').style.display = 'block'; } function clearDiff() { - document.querySelector('.cmap-diff').style.display = 'none'; + document.querySelector('.cmap-diff').style.display = 'none'; - document.querySelector('.cmap-diff-metadata').innerHTML = ''; - document.querySelector('.cmap-diff-metadata').style.display = 'none'; + document.querySelector('.cmap-diff-metadata').innerHTML = ''; + document.querySelector('.cmap-diff-metadata').style.display = 'none'; - document.querySelector('.cmap-diff-tags').innerHTML = ''; - document.querySelector('.cmap-diff-tags').style.display = 'none'; + document.querySelector('.cmap-diff-tags').innerHTML = ''; + document.querySelector('.cmap-diff-tags').style.display = 'none'; } //Renders the markup for a table function getDiffHTML(diff, ignoreList, header) { - var isAddedFeature = diff['changeType'].added === 'added'; + var isAddedFeature = diff['changeType'].added === 'added'; - var root = elt('table', { class: 'cmap-diff-table' }); - if (isAddedFeature) { - root.style.width = '300px'; - } + var root = elt('table', { class: 'cmap-diff-table' }); + if (isAddedFeature) { + root.style.width = '300px'; + } - if (header) { - root.appendChild( + if (header) { + root.appendChild( elt( 'thead', {}, @@ -819,89 +819,89 @@ function getDiffHTML(diff, ignoreList, header) { {}, elt( 'td', - { - colspan: isAddedFeature ? '2' : '3', - class: 'cmap-table-head' - }, + { + colspan: isAddedFeature ? '2' : '3', + class: 'cmap-table-head' + }, header ) ) ) ); - } - - var tbody = elt('tbody'); - - var types = ['added', 'deleted', 'modifiedOld', 'modifiedNew', 'unchanged']; - var sortedProps = Object.keys(diff).sort(function(keyA, keyB) { - var indexA = types.indexOf(Object.keys(diff[keyA])[0]); - var indexB = types.indexOf(Object.keys(diff[keyB])[0]); - return indexA - indexB; - }); - - sortedProps.forEach(function(prop) { - if (ignoreList.indexOf(prop) === -1) { - var tr = elt('tr'); - - var th = elt('th', { title: prop, class: 'cmap-strong' }, prop); - tr.appendChild(th); - - types.forEach(function(type) { - if (diff[prop].hasOwnProperty(type)) { - var propClass = 'diff-property cmap-scroll-styled props-diff-' + type; - if (type == 'added' && !isAddedFeature) { - var empty = elt('td', { class: propClass }); - tr.appendChild(empty); - } - - if (prop === 'changeset' && type === 'modifiedOld') { - var osmcha_link = elt( + } + + var tbody = elt('tbody'); + + var types = ['added', 'deleted', 'modifiedOld', 'modifiedNew', 'unchanged']; + var sortedProps = Object.keys(diff).sort(function(keyA, keyB) { + var indexA = types.indexOf(Object.keys(diff[keyA])[0]); + var indexB = types.indexOf(Object.keys(diff[keyB])[0]); + return indexA - indexB; + }); + + sortedProps.forEach(function(prop) { + if (ignoreList.indexOf(prop) === -1) { + var tr = elt('tr'); + + var th = elt('th', { title: prop, class: 'cmap-strong' }, prop); + tr.appendChild(th); + + types.forEach(function(type) { + if (diff[prop].hasOwnProperty(type)) { + var propClass = 'diff-property cmap-scroll-styled props-diff-' + type; + if (type == 'added' && !isAddedFeature) { + var empty = elt('td', { class: propClass }); + tr.appendChild(empty); + } + + if (prop === 'changeset' && type === 'modifiedOld') { + var osmcha_link = elt( 'a', - { - target: '_blank', - class: 'cmap-changeset-link', - href: '//osmcha.mapbox.com/changesets/' + diff[prop][type] - }, + { + target: '_blank', + class: 'cmap-changeset-link', + href: '//osmcha.mapbox.com/changesets/' + diff[prop][type] + }, diff[prop][type] ); - var td = elt('td', { class: propClass }, osmcha_link); - } else { - var td = elt('td', { class: propClass }, diff[prop][type]); - } - tr.appendChild(td); - - if (type == 'deleted') { - var empty = elt('td', { class: propClass }); - tr.appendChild(empty); - } - - if (type == 'unchanged') { - tr.appendChild(td.cloneNode(true)); - } - } - }); - - tbody.appendChild(tr); + var td = elt('td', { class: propClass }, osmcha_link); + } else { + var td = elt('td', { class: propClass }, diff[prop][type]); + } + tr.appendChild(td); + + if (type == 'deleted') { + var empty = elt('td', { class: propClass }); + tr.appendChild(empty); + } + + if (type == 'unchanged') { + tr.appendChild(td.cloneNode(true)); + } } - }); + }); - root.appendChild(tbody); + tbody.appendChild(tr); + } + }); + + root.appendChild(tbody); - return root; + return root; } // Recursively adds html elements function elt(name, attributes) { - var node = document.createElement(name); - if (attributes) { - for (var attr in attributes) - if (attributes.hasOwnProperty(attr)) - node.setAttribute(attr, attributes[attr]); - } - for (var i = 2; i < arguments.length; i++) { - var child = arguments[i]; - if (typeof child == 'string') child = document.createTextNode(child); - node.appendChild(child); - } - return node; + var node = document.createElement(name); + if (attributes) { + for (var attr in attributes) + if (attributes.hasOwnProperty(attr)) + node.setAttribute(attr, attributes[attr]); + } + for (var i = 2; i < arguments.length; i++) { + var child = arguments[i]; + if (typeof child == 'string') child = document.createTextNode(child); + node.appendChild(child); + } + return node; } diff --git a/lib/propsDiff.js b/lib/propsDiff.js index 2854759..8ea02eb 100644 --- a/lib/propsDiff.js +++ b/lib/propsDiff.js @@ -1,71 +1,71 @@ export function propsDiff(propsArray) { // Edge case: features may be duplicated. See issue #122. // If the changeType is `added` ignore the second feature. - if (propsArray.length === 1 || propsArray[0].changeType === 'added') { - var changeType = propsArray[0].changeType; - if (changeType === 'added') { - return getAdded(propsArray[0]); - } else { - throw new Error('only 1 element but neither added nor deleted'); - } + if (propsArray.length === 1 || propsArray[0].changeType === 'added') { + var changeType = propsArray[0].changeType; + if (changeType === 'added') { + return getAdded(propsArray[0]); } else { - var oldProps = getOld(propsArray); - var newProps = getNew(propsArray); - return getDiff(oldProps, newProps); + throw new Error('only 1 element but neither added nor deleted'); } + } else { + var oldProps = getOld(propsArray); + var newProps = getNew(propsArray); + return getDiff(oldProps, newProps); + } } function getDiff(oldProps, newProps) { - var ret = {}; - for (var prop in newProps) { - ret[prop] = {}; - if (!oldProps.hasOwnProperty(prop)) { - ret[prop]['added'] = newProps[prop]; - } else { - var oldValue = oldProps[prop]; - var newValue = newProps[prop]; - if (oldValue === newValue) { - ret[prop]['unchanged'] = newValue; - } else { - ret[prop]['modifiedOld'] = oldValue; - ret[prop]['modifiedNew'] = newValue; - } - } + var ret = {}; + for (var prop in newProps) { + ret[prop] = {}; + if (!oldProps.hasOwnProperty(prop)) { + ret[prop]['added'] = newProps[prop]; + } else { + var oldValue = oldProps[prop]; + var newValue = newProps[prop]; + if (oldValue === newValue) { + ret[prop]['unchanged'] = newValue; + } else { + ret[prop]['modifiedOld'] = oldValue; + ret[prop]['modifiedNew'] = newValue; + } } - for (var oldProp in oldProps) { - if (!ret.hasOwnProperty(oldProp)) { - ret[oldProp] = { - deleted: oldProps[oldProp] - }; - } + } + for (var oldProp in oldProps) { + if (!ret.hasOwnProperty(oldProp)) { + ret[oldProp] = { + deleted: oldProps[oldProp] + }; } - return ret; + } + return ret; } function getAdded(props) { - var ret = {}; - for (var prop in props) { - ret[prop] = { - added: props[prop] - }; - } - return ret; + var ret = {}; + for (var prop in props) { + ret[prop] = { + added: props[prop] + }; + } + return ret; } function getOld(propsArray) { - for (var i = 0; i < propsArray.length; i++) { - var changeType = propsArray[i].changeType; - if (changeType === 'modifiedOld' || changeType === 'deletedOld') { - return propsArray[i]; - } + for (var i = 0; i < propsArray.length; i++) { + var changeType = propsArray[i].changeType; + if (changeType === 'modifiedOld' || changeType === 'deletedOld') { + return propsArray[i]; } + } } function getNew(propsArray) { - for (var i = 0; i < propsArray.length; i++) { - var changeType = propsArray[i].changeType; - if (changeType === 'modifiedNew' || changeType === 'deletedNew') { - return propsArray[i]; - } + for (var i = 0; i < propsArray.length; i++) { + var changeType = propsArray[i].changeType; + if (changeType === 'modifiedNew' || changeType === 'deletedNew') { + return propsArray[i]; } + } } diff --git a/lib/query.js b/lib/query.js index 96d8e44..c3ecd6c 100644 --- a/lib/query.js +++ b/lib/query.js @@ -2,43 +2,45 @@ import moment from 'moment'; import { config } from './config'; import React from 'react'; export function query(changesetID) { - var url = config.osmBase + 'changeset/' + changesetID; - var options = { - 'Response-Type': 'document' - }; - return fetch(url, options).then(r => r.text()).then(r => { - const parser = new DOMParser(); - let xml; - try { - xml = parser.parseFromString(r, 'text/xml'); - } catch (e) { - throw e; + var url = config.osmBase + 'changeset/' + changesetID; + var options = { + 'Response-Type': 'document' + }; + return fetch(url, options) + .then(r => r.text()) + .then(r => { + const parser = new DOMParser(); + let xml; + try { + xml = parser.parseFromString(r, 'text/xml'); + } catch (e) { + throw e; + } + var csFeature = xml.getElementsByTagName('changeset')[0]; + var cs = csFeature.attributes; + var uid = cs.uid.textContent; + var user = cs.user.textContent; + var from = moment(cs.created_at.textContent, 'YYYY-MM-DDTHH:mm:ss\\Z') + .subtract('seconds', 1) + .format('YYYY-MM-DDTHH:mm:ss\\Z'); + var to = cs.closed_at ? cs.closed_at.textContent : null; + var left = cs.min_lon ? cs.min_lon.textContent : -180; + var bottom = cs.min_lat ? cs.min_lat.textContent : -90; + var right = cs.max_lon ? cs.max_lon.textContent : 180; + var top = cs.max_lat ? cs.max_lat.textContent : 90; + return { + id: changesetID, + uid: uid, + user: user, + from: from, + to: to, + bbox: { + left: left, + bottom: bottom, + right: right, + top: top } - var csFeature = xml.getElementsByTagName('changeset')[0]; - var cs = csFeature.attributes; - var uid = cs.uid.textContent; - var user = cs.user.textContent; - var from = moment(cs.created_at.textContent, 'YYYY-MM-DDTHH:mm:ss\\Z') - .subtract('seconds', 1) - .format('YYYY-MM-DDTHH:mm:ss\\Z'); - var to = cs.closed_at ? cs.closed_at.textContent : null; - var left = cs.min_lon ? cs.min_lon.textContent : -180; - var bottom = cs.min_lat ? cs.min_lat.textContent : -90; - var right = cs.max_lon ? cs.max_lon.textContent : 180; - var top = cs.max_lat ? cs.max_lat.textContent : 90; - return { - id: changesetID, - uid: uid, - user: user, - from: from, - to: to, - bbox: { - left: left, - bottom: bottom, - right: right, - top: top - } - }; + }; }); } diff --git a/lib/render.js b/lib/render.js index 4446336..0b7da51 100644 --- a/lib/render.js +++ b/lib/render.js @@ -16,74 +16,74 @@ let map; window.cmap = cmap; export function render(container, changesetId, options) { - container.style.width = options.width || '1000px'; - container.style.height = options.height || '500px'; - - options = options || {}; - options.overpassBase = options.overpassBase || config.overpassBase; - mapboxgl.accessToken = config.mapboxAccessToken; - container.classList.add('cmap-loading'); - if (!map) { - map = new GlMap(); - } - - if (options.data) { - _render(container, changesetId, options.data); - } else { - getChangeset(changesetId, options.overpassBase) + container.style.width = options.width || '1000px'; + container.style.height = options.height || '500px'; + + options = options || {}; + options.overpassBase = options.overpassBase || config.overpassBase; + mapboxgl.accessToken = config.mapboxAccessToken; + container.classList.add('cmap-loading'); + if (!map) { + map = new GlMap(); + } + + if (options.data) { + _render(container, changesetId, options.data); + } else { + getChangeset(changesetId, options.overpassBase) .then(result => _render(container, changesetId, result)) .catch(err => { - errorMessage(err.msg); + errorMessage(err.msg); }); - } + } - return cmap; + return cmap; } function _render(container, changesetId, result) { - renderHTML(container, changesetId, result); + renderHTML(container, changesetId, result); - container.classList.remove('cmap-loading'); + container.classList.remove('cmap-loading'); - map.renderMap(false, result); + map.renderMap(false, result); - var featureMap = result.featureMap; + var featureMap = result.featureMap; - cmap.removeAllListeners(); - cmap.on('remove', () => { - map.remove(); - }); + cmap.removeAllListeners(); + cmap.on('remove', () => { + map.remove(); + }); - cmap.on('selectFeature', (geometryType, featureId) => { - if (geometryType && featureId) { - map.selectFeature(featureMap[featureId][0], featureMap); - } - }); + cmap.on('selectFeature', (geometryType, featureId) => { + if (geometryType && featureId) { + map.selectFeature(featureMap[featureId][0], featureMap); + } + }); - cmap.on('clearFeature', () => { - map.clearFeature(); - }); + cmap.on('clearFeature', () => { + map.clearFeature(); + }); } // Sets initial markup for info box and map container function renderHTML(container, changesetId, result) { - var info; - if (document.getElementById('seat')) { - info = document.getElementById('seat'); - } else { - info = document.createElement('div'); - info.id = 'seat'; - container.appendChild(info); - } - container.classList.add('cmap-container'); + var info; + if (document.getElementById('seat')) { + info = document.getElementById('seat'); + } else { + info = document.createElement('div'); + info.id = 'seat'; + container.appendChild(info); + } + container.classList.add('cmap-container'); // Add `tagsCount` to feature properties - result.geojson.features.forEach(feature => { - var tags = feature.properties.tags || {}; - feature.properties.tagsCount = Object.keys(tags).length; - }); + result.geojson.features.forEach(feature => { + var tags = feature.properties.tags || {}; + feature.properties.tagsCount = Object.keys(tags).length; + }); - reactDOM( + reactDOM(
@@ -102,21 +102,21 @@ function renderHTML(container, changesetId, result) { changesetId={changesetId} filterLayers={map.filterLayers} toggleLayer={function(e) { - var layer = e.target.value; - if (layer === 'satellite') { - map.renderMap( + var layer = e.target.value; + if (layer === 'satellite') { + map.renderMap( 'mapbox://styles/rasagy/cizp6lsah00ct2snu6gi3p16q', result ); - } + } - if (layer === 'dark') { - map.renderMap('mapbox://styles/mapbox/dark-v9', result); - } + if (layer === 'dark') { + map.renderMap('mapbox://styles/mapbox/dark-v9', result); + } - if (layer === 'streets') { - map.renderMap('mapbox://styles/mapbox/streets-v9', result); - } + if (layer === 'streets') { + map.renderMap('mapbox://styles/mapbox/streets-v9', result); + } }} />
, @@ -125,9 +125,9 @@ function renderHTML(container, changesetId, result) { } function errorMessage(message) { - message = message || 'An unexpected error occured'; - document.querySelector('.cmap-info').innerHTML = message; - document.querySelector('.cmap-sidebar').style.display = 'block'; - document.querySelector('.cmap-layer-selector').style.display = 'none'; - document.querySelector('.cmap-type-selector').style.display = 'none'; + message = message || 'An unexpected error occured'; + document.querySelector('.cmap-info').innerHTML = message; + document.querySelector('.cmap-sidebar').style.display = 'block'; + document.querySelector('.cmap-layer-selector').style.display = 'none'; + document.querySelector('.cmap-type-selector').style.display = 'none'; } diff --git a/lib/sidebar.js b/lib/sidebar.js index 5daf17e..6b6e794 100644 --- a/lib/sidebar.js +++ b/lib/sidebar.js @@ -3,60 +3,58 @@ import moment from 'moment'; import { getBounds } from './helpers'; export class Sidebar extends React.PureComponent { - constructor(props) { - super(props); - this.state = { - actions: true, - type: false, - mapStyle: false, - user: false - }; - this.toggleUser = this.toggleUser.bind(this); - this.toggleActions = this.toggleActions.bind(this); - this.toggleType = this.toggleType.bind(this); - this.toggleMapStyle = this.toggleMapStyle.bind(this); - } - toggleUser() { - this.setState({ - user: !this.state.user - }); - } - toggleActions() { - this.setState({ - actions: !this.state.actions - }); - } - toggleType() { - this.setState({ - type: !this.state.type - }); - } - toggleMapStyle() { - this.setState({ - mapStyle: !this.state.mapStyle - }); - } - render() { - const result = this.props.result; - const changesetId = this.props.changesetId; - const filterLayers = this.props.filterLayers; - var date = new Date( + constructor(props) { + super(props); + this.state = { + actions: true, + type: false, + mapStyle: false, + user: false + }; + this.toggleUser = this.toggleUser.bind(this); + this.toggleActions = this.toggleActions.bind(this); + this.toggleType = this.toggleType.bind(this); + this.toggleMapStyle = this.toggleMapStyle.bind(this); + } + toggleUser() { + this.setState({ + user: !this.state.user + }); + } + toggleActions() { + this.setState({ + actions: !this.state.actions + }); + } + toggleType() { + this.setState({ + type: !this.state.type + }); + } + toggleMapStyle() { + this.setState({ + mapStyle: !this.state.mapStyle + }); + } + render() { + const result = this.props.result; + const changesetId = this.props.changesetId; + const filterLayers = this.props.filterLayers; + var date = new Date( result.changeset.to ? result.changeset.to : result.changeset.from ); - var bbox = result.changeset.bbox; - var bounds = getBounds(bbox); - var center = bounds.getCenter(); - var userName = result.changeset.user; - var userId = result.changeset.uid; - return ( + var bbox = result.changeset.bbox; + var bounds = getBounds(bbox); + var center = bounds.getCenter(); + var userName = result.changeset.user; + var userId = result.changeset.uid; + return (
Changeset: - - {changesetId} - + {changesetId} ({moment(date).fromNow()}) @@ -97,7 +95,7 @@ export class Sidebar extends React.PureComponent { className="cmap-hlist-item cmap-noselect cmap-pointer cmap-c-link-osmhv" href={ 'http://osmhv.openstreetmap.de/changeset.jsp?id=' + - changesetId + changesetId } > OSM HV @@ -109,8 +107,8 @@ export class Sidebar extends React.PureComponent { className="cmap-hlist-item cmap-noselect cmap-pointer cmap-c-link-josm" href={ 'http://127.0.0.1:8111/import?url=http://www.openstreetmap.org/api/0.6/changeset/' + - changesetId + - '/download' + changesetId + + '/download' } > JOSM @@ -122,9 +120,9 @@ export class Sidebar extends React.PureComponent { className="cmap-hlist-item cmap-noselect cmap-pointer cmap-c-link-id" href={ 'http://preview.ideditor.com/release#map=15/' + - center.lat + - '/' + - center.lng + center.lat + + '/' + + center.lng } > iD @@ -135,15 +133,13 @@ export class Sidebar extends React.PureComponent {
{this.state.user ? '▼' : '▶'} - User: - {' '} - {userName} + User: {userName}
  • @@ -170,7 +166,7 @@ export class Sidebar extends React.PureComponent { className="cmap-hlist-item cmap-noselect cmap-pointer cmap-u-link-disc" href={ 'http://resultmaps.neis-one.org/osm-discussion-comments?uid=' + - userId + userId } > Discussions @@ -182,8 +178,8 @@ export class Sidebar extends React.PureComponent { className="cmap-hlist-item cmap-noselect cmap-pointer cmap-u-link-comm" href={ 'http://resultmaps.neis-one.org/osm-discussion-comments?uid=115894' + - userId + - '&commented' + userId + + '&commented' } > Comments @@ -198,7 +194,7 @@ export class Sidebar extends React.PureComponent {
      @@ -211,9 +207,7 @@ export class Sidebar extends React.PureComponent { id="cmap-layer-selector-added" onChange={filterLayers} /> - - Added - + Added @@ -226,9 +220,7 @@ export class Sidebar extends React.PureComponent { id="cmap-layer-selector-modified" onChange={filterLayers} /> - - Modified - + Modified @@ -243,9 +235,7 @@ export class Sidebar extends React.PureComponent { id="cmap-layer-selector-deleted" onChange={filterLayers} /> - - Deleted - + Deleted @@ -258,7 +248,7 @@ export class Sidebar extends React.PureComponent {
      • @@ -270,9 +260,7 @@ export class Sidebar extends React.PureComponent { id="cmap-type-selector-nodes" onChange={filterLayers} /> - - Nodes - + Nodes
      • @@ -284,9 +272,7 @@ export class Sidebar extends React.PureComponent { id="cmap-type-selector-ways" onChange={filterLayers} /> - - Ways - + Ways
      • @@ -298,9 +284,7 @@ export class Sidebar extends React.PureComponent { id="cmap-type-selector-relations" onChange={filterLayers} /> - - Relations - + Relations
      @@ -313,7 +297,7 @@ export class Sidebar extends React.PureComponent {
      • @@ -326,9 +310,7 @@ export class Sidebar extends React.PureComponent { id="cmap-baselayer-satellite" onChange={this.props.toggleLayer} /> - - Satellite - + Satellite
      • @@ -340,9 +322,7 @@ export class Sidebar extends React.PureComponent { id="cmap-baselayer-streets" onChange={this.props.toggleLayer} /> - - Streets - + Streets
      • @@ -354,14 +334,12 @@ export class Sidebar extends React.PureComponent { id="cmap-baselayer-dark" onChange={this.props.toggleLayer} /> - - Dark - + Dark
- ); - } + ); + } } diff --git a/public/css/mapbox-gl.css b/public/css/mapbox-gl.css index 7e5875c..8ffa9d1 100644 --- a/public/css/mapbox-gl.css +++ b/public/css/mapbox-gl.css @@ -1,299 +1,330 @@ .cmap-container .mapboxgl-map { - font: 12px/20px 'Helvetica Neue', Arial, Helvetica, sans-serif; - overflow: hidden; - position: relative; - -webkit-tap-highlight-color: rgba(0,0,0,0); + font: 12px/20px "Helvetica Neue", Arial, Helvetica, sans-serif; + overflow: hidden; + position: relative; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } .mapboxgl-canvas-container.mapboxgl-interactive, .mapboxgl-ctrl-nav-compass { - cursor: -webkit-grab; - cursor: -moz-grab; - cursor: grab; + cursor: -webkit-grab; + cursor: -moz-grab; + cursor: grab; } .mapboxgl-canvas-container.mapboxgl-interactive:active, .mapboxgl-ctrl-nav-compass:active { - cursor: -webkit-grabbing; - cursor: -moz-grabbing; - cursor: grabbing; + cursor: -webkit-grabbing; + cursor: -moz-grabbing; + cursor: grabbing; } .mapboxgl-ctrl-top-left, .mapboxgl-ctrl-top-right, .mapboxgl-ctrl-bottom-left, -.mapboxgl-ctrl-bottom-right { position:absolute; pointer-events:none; z-index:2; } -.mapboxgl-ctrl-top-left { top:0; left:0; } -.mapboxgl-ctrl-top-right { top:0; right:0; } -.mapboxgl-ctrl-bottom-left { bottom:0; left:0; } -.mapboxgl-ctrl-bottom-right { right:0; bottom:0; } +.mapboxgl-ctrl-bottom-right { + position: absolute; + pointer-events: none; + z-index: 2; +} +.mapboxgl-ctrl-top-left { + top: 0; + left: 0; +} +.mapboxgl-ctrl-top-right { + top: 0; + right: 0; +} +.mapboxgl-ctrl-bottom-left { + bottom: 0; + left: 0; +} +.mapboxgl-ctrl-bottom-right { + right: 0; + bottom: 0; +} -.mapboxgl-ctrl { clear:both; pointer-events:auto } -.mapboxgl-ctrl-top-left .mapboxgl-ctrl { margin:10px 0 0 10px; float:left; } -.mapboxgl-ctrl-top-right .mapboxgl-ctrl{ margin:10px 10px 0 0; float:right; } -.mapboxgl-ctrl-bottom-left .mapboxgl-ctrl { margin:0 0 10px 10px; float:left; } -.mapboxgl-ctrl-bottom-right .mapboxgl-ctrl { margin:0 10px 10px 0; float:right; } +.mapboxgl-ctrl { + clear: both; + pointer-events: auto; +} +.mapboxgl-ctrl-top-left .mapboxgl-ctrl { + margin: 10px 0 0 10px; + float: left; +} +.mapboxgl-ctrl-top-right .mapboxgl-ctrl { + margin: 10px 10px 0 0; + float: right; +} +.mapboxgl-ctrl-bottom-left .mapboxgl-ctrl { + margin: 0 0 10px 10px; + float: left; +} +.mapboxgl-ctrl-bottom-right .mapboxgl-ctrl { + margin: 0 10px 10px 0; + float: right; +} .mapboxgl-ctrl-group { - border-radius: 4px; - -moz-box-shadow: 0px 0px 2px rgba(0,0,0,0.1); - -webkit-box-shadow: 0px 0px 2px rgba(0,0,0,0.1); - box-shadow: 0px 0px 0px 2px rgba(0,0,0,0.1); - overflow: hidden; - background: #fff; + border-radius: 4px; + -moz-box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.1); + -webkit-box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.1); + box-shadow: 0px 0px 0px 2px rgba(0, 0, 0, 0.1); + overflow: hidden; + background: #fff; } .mapboxgl-ctrl-group > button { - width: 30px; - height: 30px; - display: block; - padding: 0; - outline: none; - border: none; - border-bottom: 1px solid #ddd; - box-sizing: border-box; - background-color: rgba(0,0,0,0); - cursor: pointer; + width: 30px; + height: 30px; + display: block; + padding: 0; + outline: none; + border: none; + border-bottom: 1px solid #ddd; + box-sizing: border-box; + background-color: rgba(0, 0, 0, 0); + cursor: pointer; } /* https://bugzilla.mozilla.org/show_bug.cgi?id=140562 */ .mapboxgl-ctrl > button::-moz-focus-inner { - border: 0; - padding: 0; + border: 0; + padding: 0; } .mapboxgl-ctrl > button:last-child { - border-bottom: 0; + border-bottom: 0; } .mapboxgl-ctrl > button:hover { - background-color: rgba(0,0,0,0.05); + background-color: rgba(0, 0, 0, 0.05); } .mapboxgl-ctrl-icon, .mapboxgl-ctrl-icon > span.arrow { - speak: none; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; + speak: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; } .mapboxgl-ctrl-icon { - padding: 5px; + padding: 5px; } .mapboxgl-ctrl-icon.mapboxgl-ctrl-zoom-out { - background-image: url("data:image/svg+xml;charset=utf8,%3Csvg%20viewBox%3D%270%200%2020%2020%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%0A%20%20%3Cpath%20style%3D%27fill%3A%23333333%3B%27%20d%3D%27m%207%2C9%20c%20-0.554%2C0%20-1%2C0.446%20-1%2C1%200%2C0.554%200.446%2C1%201%2C1%20l%206%2C0%20c%200.554%2C0%201%2C-0.446%201%2C-1%200%2C-0.554%20-0.446%2C-1%20-1%2C-1%20z%27%20%2F%3E%0A%3C%2Fsvg%3E%0A"); + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg%20viewBox%3D%270%200%2020%2020%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%0A%20%20%3Cpath%20style%3D%27fill%3A%23333333%3B%27%20d%3D%27m%207%2C9%20c%20-0.554%2C0%20-1%2C0.446%20-1%2C1%200%2C0.554%200.446%2C1%201%2C1%20l%206%2C0%20c%200.554%2C0%201%2C-0.446%201%2C-1%200%2C-0.554%20-0.446%2C-1%20-1%2C-1%20z%27%20%2F%3E%0A%3C%2Fsvg%3E%0A"); } .mapboxgl-ctrl-icon.mapboxgl-ctrl-zoom-in { - background-image: url("data:image/svg+xml;charset=utf8,%3Csvg%20viewBox%3D%270%200%2020%2020%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%0A%20%20%3Cpath%20style%3D%27fill%3A%23333333%3B%27%20d%3D%27M%2010%206%20C%209.446%206%209%206.4459904%209%207%20L%209%209%20L%207%209%20C%206.446%209%206%209.446%206%2010%20C%206%2010.554%206.446%2011%207%2011%20L%209%2011%20L%209%2013%20C%209%2013.55401%209.446%2014%2010%2014%20C%2010.554%2014%2011%2013.55401%2011%2013%20L%2011%2011%20L%2013%2011%20C%2013.554%2011%2014%2010.554%2014%2010%20C%2014%209.446%2013.554%209%2013%209%20L%2011%209%20L%2011%207%20C%2011%206.4459904%2010.554%206%2010%206%20z%27%20%2F%3E%0A%3C%2Fsvg%3E%0A"); + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg%20viewBox%3D%270%200%2020%2020%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%0A%20%20%3Cpath%20style%3D%27fill%3A%23333333%3B%27%20d%3D%27M%2010%206%20C%209.446%206%209%206.4459904%209%207%20L%209%209%20L%207%209%20C%206.446%209%206%209.446%206%2010%20C%206%2010.554%206.446%2011%207%2011%20L%209%2011%20L%209%2013%20C%209%2013.55401%209.446%2014%2010%2014%20C%2010.554%2014%2011%2013.55401%2011%2013%20L%2011%2011%20L%2013%2011%20C%2013.554%2011%2014%2010.554%2014%2010%20C%2014%209.446%2013.554%209%2013%209%20L%2011%209%20L%2011%207%20C%2011%206.4459904%2010.554%206%2010%206%20z%27%20%2F%3E%0A%3C%2Fsvg%3E%0A"); } -.mapboxgl-ctrl-icon.mapboxgl-ctrl-geolocate { - background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D%270%200%2020%2020%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%0D%0A%20%20%3Cpath%20style%3D%27fill%3A%23333%3B%27%20d%3D%27M10%204C9%204%209%205%209%205L9%205.1A5%205%200%200%200%205.1%209L5%209C5%209%204%209%204%2010%204%2011%205%2011%205%2011L5.1%2011A5%205%200%200%200%209%2014.9L9%2015C9%2015%209%2016%2010%2016%2011%2016%2011%2015%2011%2015L11%2014.9A5%205%200%200%200%2014.9%2011L15%2011C15%2011%2016%2011%2016%2010%2016%209%2015%209%2015%209L14.9%209A5%205%200%200%200%2011%205.1L11%205C11%205%2011%204%2010%204zM10%206.5A3.5%203.5%200%200%201%2013.5%2010%203.5%203.5%200%200%201%2010%2013.5%203.5%203.5%200%200%201%206.5%2010%203.5%203.5%200%200%201%2010%206.5zM10%208.3A1.8%201.8%200%200%200%208.3%2010%201.8%201.8%200%200%200%2010%2011.8%201.8%201.8%200%200%200%2011.8%2010%201.8%201.8%200%200%200%2010%208.3z%27%20%2F%3E%0D%0A%3C%2Fsvg%3E"); +.mapboxgl-ctrl-icon.mapboxgl-ctrl-geolocate { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D%270%200%2020%2020%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%0D%0A%20%20%3Cpath%20style%3D%27fill%3A%23333%3B%27%20d%3D%27M10%204C9%204%209%205%209%205L9%205.1A5%205%200%200%200%205.1%209L5%209C5%209%204%209%204%2010%204%2011%205%2011%205%2011L5.1%2011A5%205%200%200%200%209%2014.9L9%2015C9%2015%209%2016%2010%2016%2011%2016%2011%2015%2011%2015L11%2014.9A5%205%200%200%200%2014.9%2011L15%2011C15%2011%2016%2011%2016%2010%2016%209%2015%209%2015%209L14.9%209A5%205%200%200%200%2011%205.1L11%205C11%205%2011%204%2010%204zM10%206.5A3.5%203.5%200%200%201%2013.5%2010%203.5%203.5%200%200%201%2010%2013.5%203.5%203.5%200%200%201%206.5%2010%203.5%203.5%200%200%201%2010%206.5zM10%208.3A1.8%201.8%200%200%200%208.3%2010%201.8%201.8%200%200%200%2010%2011.8%201.8%201.8%200%200%200%2011.8%2010%201.8%201.8%200%200%200%2010%208.3z%27%20%2F%3E%0D%0A%3C%2Fsvg%3E"); } -.mapboxgl-ctrl-icon.mapboxgl-ctrl-geolocate.watching { - background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D%270%200%2020%2020%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%0D%0A%20%20%3Cpath%20style%3D%27fill%3A%2300f%3B%27%20d%3D%27M10%204C9%204%209%205%209%205L9%205.1A5%205%200%200%200%205.1%209L5%209C5%209%204%209%204%2010%204%2011%205%2011%205%2011L5.1%2011A5%205%200%200%200%209%2014.9L9%2015C9%2015%209%2016%2010%2016%2011%2016%2011%2015%2011%2015L11%2014.9A5%205%200%200%200%2014.9%2011L15%2011C15%2011%2016%2011%2016%2010%2016%209%2015%209%2015%209L14.9%209A5%205%200%200%200%2011%205.1L11%205C11%205%2011%204%2010%204zM10%206.5A3.5%203.5%200%200%201%2013.5%2010%203.5%203.5%200%200%201%2010%2013.5%203.5%203.5%200%200%201%206.5%2010%203.5%203.5%200%200%201%2010%206.5zM10%208.3A1.8%201.8%200%200%200%208.3%2010%201.8%201.8%200%200%200%2010%2011.8%201.8%201.8%200%200%200%2011.8%2010%201.8%201.8%200%200%200%2010%208.3z%27%20%2F%3E%0D%0A%3C%2Fsvg%3E"); +.mapboxgl-ctrl-icon.mapboxgl-ctrl-geolocate.watching { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D%270%200%2020%2020%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%0D%0A%20%20%3Cpath%20style%3D%27fill%3A%2300f%3B%27%20d%3D%27M10%204C9%204%209%205%209%205L9%205.1A5%205%200%200%200%205.1%209L5%209C5%209%204%209%204%2010%204%2011%205%2011%205%2011L5.1%2011A5%205%200%200%200%209%2014.9L9%2015C9%2015%209%2016%2010%2016%2011%2016%2011%2015%2011%2015L11%2014.9A5%205%200%200%200%2014.9%2011L15%2011C15%2011%2016%2011%2016%2010%2016%209%2015%209%2015%209L14.9%209A5%205%200%200%200%2011%205.1L11%205C11%205%2011%204%2010%204zM10%206.5A3.5%203.5%200%200%201%2013.5%2010%203.5%203.5%200%200%201%2010%2013.5%203.5%203.5%200%200%201%206.5%2010%203.5%203.5%200%200%201%2010%206.5zM10%208.3A1.8%201.8%200%200%200%208.3%2010%201.8%201.8%200%200%200%2010%2011.8%201.8%201.8%200%200%200%2011.8%2010%201.8%201.8%200%200%200%2010%208.3z%27%20%2F%3E%0D%0A%3C%2Fsvg%3E"); } .mapboxgl-ctrl-icon.mapboxgl-ctrl-compass > span.arrow { - width: 20px; - height: 20px; - margin: 5px; - background-image: url("data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2020%2020%27%3E%0A%09%3Cpolygon%20fill%3D%27%23333333%27%20points%3D%276%2C9%2010%2C1%2014%2C9%27%2F%3E%0A%09%3Cpolygon%20fill%3D%27%23CCCCCC%27%20points%3D%276%2C11%2010%2C19%2014%2C11%20%27%2F%3E%0A%3C%2Fsvg%3E"); - background-repeat: no-repeat; - display: inline-block; + width: 20px; + height: 20px; + margin: 5px; + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2020%2020%27%3E%0A%09%3Cpolygon%20fill%3D%27%23333333%27%20points%3D%276%2C9%2010%2C1%2014%2C9%27%2F%3E%0A%09%3Cpolygon%20fill%3D%27%23CCCCCC%27%20points%3D%276%2C11%2010%2C19%2014%2C11%20%27%2F%3E%0A%3C%2Fsvg%3E"); + background-repeat: no-repeat; + display: inline-block; } .mapboxgl-ctrl.mapboxgl-ctrl-attrib { - padding: 0 5px; - background-color: rgba(255, 255, 255, .5); - margin: 0; + padding: 0 5px; + background-color: rgba(255, 255, 255, 0.5); + margin: 0; } .mapboxgl-ctrl-attrib.compact { - padding-top: 2px; - padding-bottom: 2px; - margin: 0 10px 10px 10px; - position: relative; - padding-right: 24px; - background-color: #fff; - border-radius: 3px 12px 12px 3px; - visibility: hidden; + padding-top: 2px; + padding-bottom: 2px; + margin: 0 10px 10px 10px; + position: relative; + padding-right: 24px; + background-color: #fff; + border-radius: 3px 12px 12px 3px; + visibility: hidden; } .mapboxgl-ctrl-attrib.compact:hover { - visibility: visible; + visibility: visible; } .mapboxgl-ctrl-attrib.compact:after { - content: ''; - cursor: pointer; - position: absolute; - bottom: 0; - right: 0; - background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D%270%200%2020%2020%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%0D%0A%09%3Cpath%20fill%3D%27%23333333%27%20fill-rule%3D%27evenodd%27%20d%3D%27M4%2C10a6%2C6%200%201%2C0%2012%2C0a6%2C6%200%201%2C0%20-12%2C0%20M9%2C7a1%2C1%200%201%2C0%202%2C0a1%2C1%200%201%2C0%20-2%2C0%20M9%2C10a1%2C1%200%201%2C1%202%2C0l0%2C3a1%2C1%200%201%2C1%20-2%2C0%27%20%2F%3E%0D%0A%3C%2Fsvg%3E"); - background-color: rgba(255, 255, 255, .5); - width: 24px; - height: 24px; - box-sizing: border-box; - visibility: visible; - border-radius: 12px; + content: ""; + cursor: pointer; + position: absolute; + bottom: 0; + right: 0; + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D%270%200%2020%2020%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%0D%0A%09%3Cpath%20fill%3D%27%23333333%27%20fill-rule%3D%27evenodd%27%20d%3D%27M4%2C10a6%2C6%200%201%2C0%2012%2C0a6%2C6%200%201%2C0%20-12%2C0%20M9%2C7a1%2C1%200%201%2C0%202%2C0a1%2C1%200%201%2C0%20-2%2C0%20M9%2C10a1%2C1%200%201%2C1%202%2C0l0%2C3a1%2C1%200%201%2C1%20-2%2C0%27%20%2F%3E%0D%0A%3C%2Fsvg%3E"); + background-color: rgba(255, 255, 255, 0.5); + width: 24px; + height: 24px; + box-sizing: border-box; + visibility: visible; + border-radius: 12px; } .mapboxgl-ctrl-attrib a { - color: rgba(0,0,0,0.75); - text-decoration: none; + color: rgba(0, 0, 0, 0.75); + text-decoration: none; } .mapboxgl-ctrl-attrib a:hover { - color: inherit; - text-decoration: underline; + color: inherit; + text-decoration: underline; } .mapboxgl-ctrl-attrib .mapbox-improve-map { - font-weight: bold; - margin-left: 2px; + font-weight: bold; + margin-left: 2px; } .mapboxgl-ctrl-scale { - background-color: rgba(255,255,255,0.75); - font-size: 10px; - border-width: medium 2px 2px; - border-style: none solid solid; - border-color: #333; - padding: 0 5px; - color: #333; + background-color: rgba(255, 255, 255, 0.75); + font-size: 10px; + border-width: medium 2px 2px; + border-style: none solid solid; + border-color: #333; + padding: 0 5px; + color: #333; } .mapboxgl-popup { - position: absolute; - top: 0; - left: 0; - display: -webkit-flex; - display: flex; - will-change: transform; - pointer-events: none; + position: absolute; + top: 0; + left: 0; + display: -webkit-flex; + display: flex; + will-change: transform; + pointer-events: none; } .mapboxgl-popup-anchor-top, .mapboxgl-popup-anchor-top-left, .mapboxgl-popup-anchor-top-right { - -webkit-flex-direction: column; - flex-direction: column; + -webkit-flex-direction: column; + flex-direction: column; } .mapboxgl-popup-anchor-bottom, .mapboxgl-popup-anchor-bottom-left, .mapboxgl-popup-anchor-bottom-right { - -webkit-flex-direction: column-reverse; - flex-direction: column-reverse; + -webkit-flex-direction: column-reverse; + flex-direction: column-reverse; } .mapboxgl-popup-anchor-left { - -webkit-flex-direction: row; - flex-direction: row; + -webkit-flex-direction: row; + flex-direction: row; } .mapboxgl-popup-anchor-right { - -webkit-flex-direction: row-reverse; - flex-direction: row-reverse; + -webkit-flex-direction: row-reverse; + flex-direction: row-reverse; } .mapboxgl-popup-tip { - width: 0; - height: 0; - border: 10px solid transparent; - z-index: 1; + width: 0; + height: 0; + border: 10px solid transparent; + z-index: 1; } .mapboxgl-popup-anchor-top .mapboxgl-popup-tip { - -webkit-align-self: center; - align-self: center; - border-top: none; - border-bottom-color: #fff; + -webkit-align-self: center; + align-self: center; + border-top: none; + border-bottom-color: #fff; } .mapboxgl-popup-anchor-top-left .mapboxgl-popup-tip { - -webkit-align-self: flex-start; - align-self: flex-start; - border-top: none; - border-left: none; - border-bottom-color: #fff; + -webkit-align-self: flex-start; + align-self: flex-start; + border-top: none; + border-left: none; + border-bottom-color: #fff; } .mapboxgl-popup-anchor-top-right .mapboxgl-popup-tip { - -webkit-align-self: flex-end; - align-self: flex-end; - border-top: none; - border-right: none; - border-bottom-color: #fff; + -webkit-align-self: flex-end; + align-self: flex-end; + border-top: none; + border-right: none; + border-bottom-color: #fff; } .mapboxgl-popup-anchor-bottom .mapboxgl-popup-tip { - -webkit-align-self: center; - align-self: center; - border-bottom: none; - border-top-color: #fff; + -webkit-align-self: center; + align-self: center; + border-bottom: none; + border-top-color: #fff; } .mapboxgl-popup-anchor-bottom-left .mapboxgl-popup-tip { - -webkit-align-self: flex-start; - align-self: flex-start; - border-bottom: none; - border-left: none; - border-top-color: #fff; + -webkit-align-self: flex-start; + align-self: flex-start; + border-bottom: none; + border-left: none; + border-top-color: #fff; } .mapboxgl-popup-anchor-bottom-right .mapboxgl-popup-tip { - -webkit-align-self: flex-end; - align-self: flex-end; - border-bottom: none; - border-right: none; - border-top-color: #fff; + -webkit-align-self: flex-end; + align-self: flex-end; + border-bottom: none; + border-right: none; + border-top-color: #fff; } .mapboxgl-popup-anchor-left .mapboxgl-popup-tip { - -webkit-align-self: center; - align-self: center; - border-left: none; - border-right-color: #fff; + -webkit-align-self: center; + align-self: center; + border-left: none; + border-right-color: #fff; } .mapboxgl-popup-anchor-right .mapboxgl-popup-tip { - -webkit-align-self: center; - align-self: center; - border-right: none; - border-left-color: #fff; + -webkit-align-self: center; + align-self: center; + border-right: none; + border-left-color: #fff; } .mapboxgl-popup-close-button { - position: absolute; - right: 0; - top: 0; - border: none; - border-radius: 0 3px 0 0; - cursor: pointer; - background-color: rgba(0,0,0,0); + position: absolute; + right: 0; + top: 0; + border: none; + border-radius: 0 3px 0 0; + cursor: pointer; + background-color: rgba(0, 0, 0, 0); } .mapboxgl-popup-close-button:hover { - background-color: rgba(0,0,0,0.05); + background-color: rgba(0, 0, 0, 0.05); } .mapboxgl-popup-content { - position: relative; - background: #fff; - border-radius: 3px; - box-shadow: 0 1px 2px rgba(0,0,0,0.10); - padding: 10px 10px 15px; - pointer-events: auto; + position: relative; + background: #fff; + border-radius: 3px; + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); + padding: 10px 10px 15px; + pointer-events: auto; } .mapboxgl-popup-anchor-top-left .mapboxgl-popup-content { - border-top-left-radius: 0; + border-top-left-radius: 0; } .mapboxgl-popup-anchor-top-right .mapboxgl-popup-content { - border-top-right-radius: 0; + border-top-right-radius: 0; } .mapboxgl-popup-anchor-bottom-left .mapboxgl-popup-content { - border-bottom-left-radius: 0; + border-bottom-left-radius: 0; } .mapboxgl-popup-anchor-bottom-right .mapboxgl-popup-content { - border-bottom-right-radius: 0; + border-bottom-right-radius: 0; } .mapboxgl-marker { - position: absolute; - top: 0; - left: 0; - will-change: transform; + position: absolute; + top: 0; + left: 0; + will-change: transform; } .mapboxgl-crosshair, .mapboxgl-crosshair .mapboxgl-interactive, .mapboxgl-crosshair .mapboxgl-interactive:active { - cursor: crosshair; + cursor: crosshair; } .mapboxgl-boxzoom { - position: absolute; - top: 0; - left: 0; - width: 0; - height: 0; - background: #fff; - border: 2px dotted #202020; - opacity: 0.5; + position: absolute; + top: 0; + left: 0; + width: 0; + height: 0; + background: #fff; + border: 2px dotted #202020; + opacity: 0.5; } @media print { - .mapbox-improve-map { - display:none; - } + .mapbox-improve-map { + display: none; + } } diff --git a/rollup.plugin.config.js b/rollup.plugin.config.js index 113c93a..7a38aa2 100644 --- a/rollup.plugin.config.js +++ b/rollup.plugin.config.js @@ -8,39 +8,39 @@ import eslint from 'rollup-plugin-eslint'; import sizes from 'rollup-plugin-sizes'; import uglify from 'rollup-plugin-uglify'; export default { - entry: 'lib/index.js', - dest: 'dist/bundle.js', - format: 'cjs', - sourceMap: false, - plugins: [ - eslint({ - exclude: ['src/styles/**'] - }), - replace({ - 'process.env.NODE_ENV': JSON.stringify('production') - }), - builtins(), - nodeResolve({ - jsnext: false, - main: true, - browser: true - }), - commonjs({ - include: ['node_modules/**'], - exclude: ['node_modules/process-es6/**'], - namedExports: { - 'node_modules/react/react.js': [ - 'Children', - 'Component', - 'PropTypes', - 'createElement' - ], - 'node_modules/react-dom/index.js': ['render'] - } - }), - babel({ - exclude: 'node_modules/**' - }), - globals() - ] + entry: 'lib/index.js', + dest: 'dist/bundle.js', + format: 'cjs', + sourceMap: false, + plugins: [ + eslint({ + exclude: ['src/styles/**'] + }), + replace({ + 'process.env.NODE_ENV': JSON.stringify('production') + }), + builtins(), + nodeResolve({ + jsnext: false, + main: true, + browser: true + }), + commonjs({ + include: ['node_modules/**'], + exclude: ['node_modules/process-es6/**'], + namedExports: { + 'node_modules/react/react.js': [ + 'Children', + 'Component', + 'PropTypes', + 'createElement' + ], + 'node_modules/react-dom/index.js': ['render'] + } + }), + babel({ + exclude: 'node_modules/**' + }), + globals() + ] }; diff --git a/www/index.js b/www/index.js index b47146e..7e28b32 100644 --- a/www/index.js +++ b/www/index.js @@ -16,48 +16,48 @@ var containerWidth = window.innerWidth + 'px'; var containerHeight = window.innerHeight + 'px'; if (location.hash !== '') { - document.getElementById('formContainer').style.display = 'none'; - var id = location.hash.split('/')[0].replace('#', ''); - var [, geometryType, featureId] = location.hash.split('/'); - cMap = changesetMap(document.getElementById('container'), id, { - width: containerWidth, - height: containerHeight - }); - cMap.on('load', function() { - cMap.emit('selectFeature', geometryType, featureId); - }); + document.getElementById('formContainer').style.display = 'none'; + var id = location.hash.split('/')[0].replace('#', ''); + var [, geometryType, featureId] = location.hash.split('/'); + cMap = changesetMap(document.getElementById('container'), id, { + width: containerWidth, + height: containerHeight + }); + cMap.on('load', function() { + cMap.emit('selectFeature', geometryType, featureId); + }); } document .getElementById('changesetForm') .addEventListener('submit', function(e) { - e.preventDefault(); - document.getElementById('formContainer').style.display = 'none'; - var changesetID = document.getElementById('changesetInput').value; - location.hash = changesetID; - cMap = changesetMap(document.getElementById('container'), changesetID, { - hash: location.hash, - width: containerWidth, - height: containerHeight - }); + e.preventDefault(); + document.getElementById('formContainer').style.display = 'none'; + var changesetID = document.getElementById('changesetInput').value; + location.hash = changesetID; + cMap = changesetMap(document.getElementById('container'), changesetID, { + hash: location.hash, + width: containerWidth, + height: containerHeight + }); }); cMap.on('featureChange', function(geometryType, featureId) { - clearHash(); - if (geometryType && featureId) { - updateHash(geometryType, featureId); - } + clearHash(); + if (geometryType && featureId) { + updateHash(geometryType, featureId); + } }); function updateHash(osmType, featureId) { - clearHash(); + clearHash(); - location.hash += '/' + osmType; - location.hash += '/' + featureId; + location.hash += '/' + osmType; + location.hash += '/' + featureId; } function clearHash() { - var changesetId = location.hash.split('/')[0].replace('#', ''); + var changesetId = location.hash.split('/')[0].replace('#', ''); - location.hash = changesetId; + location.hash = changesetId; }