UNPKG

3.94 kBJavaScriptView Raw
1import mapboxgl from 'mapbox-gl';
2import { EventEmitter as Events } from 'events';
3import { render as reactDOM } from 'react-dom';
4import React from 'react';
5
6import { getChangeset } from './getChangeset';
7import { Sidebar } from './sidebar';
8import { Map as GlMap } from './map';
9//filterLayers, renderMap, selectFeature, clearFeature
10import { config } from './config';
11
12export const cmap = new Events();
13
14let map;
15
16window.cmap = cmap;
17
18export 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}
42export function getMapInstance() {
43 return map;
44}
45export function getGL() {
46 return mapboxgl;
47}
48
49function _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// Sets initial markup for info box and map container
79function 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 // Add `tagsCount` to feature properties
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
133function 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}