1 | import mapboxgl from 'mapbox-gl';
|
2 | import { EventEmitter as Events } from 'events';
|
3 | import { render as reactDOM } from 'react-dom';
|
4 | import React from 'react';
|
5 |
|
6 | import { getChangeset } from './getChangeset';
|
7 | import { Sidebar } from './sidebar';
|
8 | import { Map as GlMap } from './map';
|
9 |
|
10 | import { config } from './config';
|
11 |
|
12 | export const cmap = new Events();
|
13 |
|
14 | let map;
|
15 |
|
16 | window.cmap = cmap;
|
17 |
|
18 | export function render(container, changesetId, options) {
|
19 | container.style.width = options.width || '1000px';
|
20 | container.style.height = options.height || '500px';
|
21 |
|
22 | options = options || {};
|
23 | options.overpassBase = options.overpassBase || config.overpassBase;
|
24 | mapboxgl.accessToken = config.mapboxAccessToken;
|
25 | container.classList.add('cmap-loading');
|
26 | if (!map) {
|
27 | map = new GlMap();
|
28 | }
|
29 |
|
30 | if (options.data) {
|
31 | _render(container, changesetId, options.data, options.disableSidebar);
|
32 | } else {
|
33 | getChangeset(changesetId, options.overpassBase)
|
34 | .then(result => _render(container, changesetId, result))
|
35 | .catch(err => {
|
36 | errorMessage(err.msg);
|
37 | });
|
38 | }
|
39 |
|
40 | return cmap;
|
41 | }
|
42 | export function getMapInstance() {
|
43 | return map;
|
44 | }
|
45 | export function getGL() {
|
46 | return mapboxgl;
|
47 | }
|
48 |
|
49 | function _render(container, changesetId, result, disableSidebar) {
|
50 | renderHTML(container, changesetId, result, disableSidebar);
|
51 |
|
52 | container.classList.remove('cmap-loading');
|
53 |
|
54 | map.renderMap(false, result);
|
55 |
|
56 | var featureMap = result.featureMap;
|
57 |
|
58 | cmap.removeAllListeners();
|
59 | cmap.on('remove', () => {
|
60 | map.remove();
|
61 | });
|
62 |
|
63 | cmap.on('selectFeature', (geometryType, featureId) => {
|
64 | if (geometryType && featureId) {
|
65 | map.selectFeature(featureMap[featureId][0], featureMap);
|
66 | map.zoomToFeatures(featureMap[featureId]);
|
67 | }
|
68 | });
|
69 | cmap.on('selectMember', featureId => {
|
70 | map.selectMember(featureId);
|
71 | });
|
72 |
|
73 | cmap.on('clearFeature', () => {
|
74 | map.clearFeature();
|
75 | });
|
76 | }
|
77 |
|
78 |
|
79 | function renderHTML(container, changesetId, result, disableSidebar) {
|
80 | var info;
|
81 | if (document.getElementById('seat')) {
|
82 | info = document.getElementById('seat');
|
83 | } else {
|
84 | info = document.createElement('div');
|
85 | info.id = 'seat';
|
86 | container.appendChild(info);
|
87 | }
|
88 | container.classList.add('cmap-container');
|
89 |
|
90 |
|
91 | result.geojson.features.forEach(feature => {
|
92 | var tags = feature.properties.tags || {};
|
93 | feature.properties.tagsCount = Object.keys(tags).length;
|
94 | });
|
95 |
|
96 | reactDOM(
|
97 | <div>
|
98 | <div className="cmap-map" />
|
99 |
|
100 | <div className="cmap-diff" style={{ display: 'none' }}>
|
101 | <div className="cmap-diff-metadata cmap-scroll-styled" />
|
102 | <div className="cmap-diff-tags cmap-scroll-styled" />
|
103 | <div className="cmap-diff-members cmap-scroll-styled" />
|
104 | </div>
|
105 | {!disableSidebar &&
|
106 | <Sidebar
|
107 | result={result}
|
108 | changesetId={changesetId}
|
109 | filterLayers={map.filterLayers}
|
110 | toggleLayer={function(e) {
|
111 | var layer = e.target.value;
|
112 | if (layer === 'satellite') {
|
113 | map.renderMap(
|
114 | 'mapbox://styles/openstreetmap/cjnd8lj0e10i42spfo4nsvoay',
|
115 | result
|
116 | );
|
117 | }
|
118 |
|
119 | if (layer === 'dark') {
|
120 | map.renderMap('mapbox://styles/mapbox/dark-v9', result);
|
121 | }
|
122 |
|
123 | if (layer === 'streets') {
|
124 | map.renderMap('mapbox://styles/mapbox/streets-v9', result);
|
125 | }
|
126 | }}
|
127 | />}
|
128 | </div>,
|
129 | info
|
130 | );
|
131 | }
|
132 |
|
133 | function errorMessage(message) {
|
134 | message = message || 'An unexpected error occured';
|
135 | document.querySelector('.cmap-info').innerHTML = message;
|
136 | document.querySelector('.cmap-sidebar').style.display = 'block';
|
137 | document.querySelector('.cmap-layer-selector').style.display = 'none';
|
138 | document.querySelector('.cmap-type-selector').style.display = 'none';
|
139 | }
|