-
-
Notifications
You must be signed in to change notification settings - Fork 300
Expand file tree
/
Copy patheditor.js
More file actions
146 lines (133 loc) · 5.27 KB
/
editor.js
File metadata and controls
146 lines (133 loc) · 5.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import { useEffect, useState } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { useIntl } from 'react-intl';
import { gpx } from '@tmcw/togeojson';
import * as iD from '@hotosm/id';
import '@hotosm/id/dist/iD.css';
import { OSM_CLIENT_ID, OSM_REDIRECT_URI, OSM_SERVER_URL } from '../config';
import messages from './messages';
export default function Editor({ setDisable, comment, presets, imagery, gpxUrl, extraIdParams }) {
const dispatch = useDispatch();
const intl = useIntl();
const session = useSelector((state) => state.auth.session);
const iDContext = useSelector((state) => state.editor.context);
const locale = useSelector((state) => state.preferences.locale);
const [customImageryIsSet, setCustomImageryIsSet] = useState(false);
const windowInit = typeof window !== 'undefined';
const customSource =
iDContext && iDContext.background() && iDContext.background().findSource('custom');
useEffect(() => {
if (!customImageryIsSet && imagery && customSource) {
if (imagery.startsWith('http')) {
iDContext.background().baseLayerSource(customSource.template(imagery));
setCustomImageryIsSet(true);
// this line is needed to update the value on the custom background dialog
window.iD.prefs('background-custom-template', imagery);
} else {
const imagerySource = iDContext.background().findSource(imagery);
if (imagerySource) {
iDContext.background().baseLayerSource(imagerySource);
}
}
}
// wait till iDContext loads background
if (!iDContext?.background()) return;
// this fixes the custom imagery persisting from previous load
// when no imagery is selected in project setting
if (!imagery) {
// set Bing as default
const imagerySource = iDContext.background().findSource('Bing');
if (!imagerySource) return;
iDContext.background().baseLayerSource(imagerySource);
}
// this sets imagery offset from extraIdParams if present
if (extraIdParams) {
const params = new URLSearchParams(extraIdParams);
const offsetStr = params.get('offset'); // "10,-10"
if (!offsetStr) return;
const offsetInMeters = offsetStr.split(',').map(Number); // [10, -10]
const offset = window.iD.geoMetersToOffset(offsetInMeters);
iDContext.background().offset(offset);
} else {
// reset offset if params not present
// this is needed to fix the offset persisting from previous project issue
iDContext.background().offset([0, 0]);
}
}, [customImageryIsSet, imagery, iDContext, customSource, extraIdParams]);
useEffect(() => {
if (windowInit) {
if (iDContext === null) {
// we need to keep iD context on redux store because iD works better if
// the context is not restarted while running in the same browser session
dispatch({ type: 'SET_EDITOR', context: window.iD.coreContext() });
}
}
}, [windowInit, iDContext, dispatch]);
useEffect(() => {
if (iDContext && comment) {
iDContext.defaultChangesetComment(comment);
}
}, [comment, iDContext]);
useEffect(() => {
if (session && locale && iD && iDContext) {
// if presets is not a populated list we need to set it as null
try {
if (presets.length) {
window.iD.presetManager.addablePresetIDs(presets);
} else {
window.iD.presetManager.addablePresetIDs(null);
}
} catch (e) {
window.iD.presetManager.addablePresetIDs(null);
}
// setup the context
iDContext
.embed(true)
.assetPath('/static/id/')
.locale(locale)
.setsDocumentTitle(false)
.containerNode(document.getElementById('id-container'));
// init the ui or restart if it was loaded previously
if (iDContext.ui() !== undefined) {
iDContext.reset();
iDContext.ui().restart();
} else {
iDContext.init();
}
if (gpxUrl) {
fetch(gpxUrl)
.then((response) => response.text())
.then((data) => {
let gpxData = new DOMParser().parseFromString(data, 'text/xml');
let nameNode = gpxData.getElementsByTagName('trk')[0].childNodes[0];
let projectId = nameNode.textContent.match(/\d+/g);
nameNode.textContent = intl.formatMessage(messages.gpxNameAttribute, {
projectId: projectId[0],
});
iDContext.layers().layer('data').geojson(gpx(gpxData));
})
.catch((error) => {
console.error('Error loading GPX data');
});
}
let osm = iDContext.connection();
var auth = {
url: OSM_SERVER_URL,
client_id: OSM_CLIENT_ID,
redirect_uri: OSM_REDIRECT_URI,
access_token: session.osm_oauth_token,
};
osm.switch(auth);
const thereAreChanges = (changes) =>
changes.modified.length || changes.created.length || changes.deleted.length;
iDContext.history().on('change', () => {
if (thereAreChanges(iDContext.history().changes())) {
setDisable(true);
} else {
setDisable(false);
}
});
}
}, [session, iDContext, setDisable, presets, locale, gpxUrl, intl]);
return <div className="w-100 vh-minus-69-ns" id="id-container"></div>;
}