]> git.argeo.org Git - gpl/argeo-suite.git/blob - swt/org.argeo.app.ui/src/org/argeo/app/ui/openlayers/OpenLayersMap.java
Load maintenance resources relative to class
[gpl/argeo-suite.git] / swt / org.argeo.app.ui / src / org / argeo / app / ui / openlayers / OpenLayersMap.java
1 package org.argeo.app.ui.openlayers;
2
3 import java.io.IOException;
4 import java.io.InputStream;
5 import java.net.URL;
6 import java.nio.charset.StandardCharsets;
7 import java.util.ArrayList;
8 import java.util.HashMap;
9 import java.util.List;
10 import java.util.Map;
11
12 import javax.jcr.Node;
13 import javax.jcr.RepositoryException;
14
15 import org.apache.commons.io.IOUtils;
16 import org.argeo.app.api.EntityNames;
17 import org.argeo.app.api.EntityType;
18 import org.argeo.app.ui.SuiteUxEvent;
19 import org.argeo.api.cms.CmsLog;
20 import org.argeo.api.cms.ux.CmsView;
21 import org.argeo.api.cms.CmsConstants;
22 import org.argeo.cms.swt.CmsSwtUtils;
23 import org.eclipse.swt.SWT;
24 import org.eclipse.swt.browser.Browser;
25 import org.eclipse.swt.browser.BrowserFunction;
26 import org.eclipse.swt.layout.GridLayout;
27 import org.eclipse.swt.widgets.Composite;
28
29 /** Display a map. */
30 public class OpenLayersMap extends Composite {
31 private static final long serialVersionUID = 1055893020490283622L;
32
33 private final static CmsLog log = CmsLog.getLog(OpenLayersMap.class);
34
35 private Browser browser;
36 private boolean renderCompleted = false;
37
38 private Double centerLng = null, centerLat = null;
39 private Integer zoom = null;
40 private String vectorSource = null;
41 private String gpxSource = null;
42
43 private String vectorSourceStyle;
44
45 private List<String> geoJsonSources = new ArrayList<>();
46 private Map<String, String> vectorSources = new HashMap<>();
47 private Map<String, String> layerStyles = new HashMap<>();
48
49 private CmsView cmsView;
50
51 public OpenLayersMap(Composite parent, int style, URL mapHtml) {
52 super(parent, style);
53 cmsView = CmsSwtUtils.getCmsView(parent);
54 setLayout(new GridLayout());
55
56 browser = new Browser(this, SWT.BORDER);
57 browser.setLayoutData(CmsSwtUtils.fillAll());
58 String html;
59 try (InputStream in = mapHtml.openStream()) {
60 html = IOUtils.toString(in, StandardCharsets.UTF_8);
61 } catch (IOException e) {
62 throw new RuntimeException(e);
63 }
64 new RenderCompleted(browser, "renderCompleted");
65 new OnFeatureSelect(browser, "onFeatureSelect");
66 new OnFeatureUnselect(browser, "onFeatureUnselect");
67 new OnFeatureClick(browser, "onFeatureClick");
68 browser.setText(html);
69 }
70
71 public void setCenter(Double lng, Double lat) {
72 if (isRenderCompleted())
73 browser.evaluate("map.getView().setCenter(ol.proj.fromLonLat([" + lng + ", " + lat + "]))");
74 this.centerLat = lat;
75 this.centerLng = lng;
76 }
77
78 public synchronized void setRenderCompleted(boolean renderCompleted) {
79 this.renderCompleted = renderCompleted;
80 notifyAll();
81 }
82
83 public synchronized boolean isRenderCompleted() {
84 return renderCompleted;
85 }
86
87 @Override
88 public synchronized void dispose() {
89 long timeout = 500;
90 long begin = System.currentTimeMillis();
91 while (!isRenderCompleted() && ((System.currentTimeMillis() - begin) < timeout)) {
92 try {
93 wait(50);
94 } catch (InterruptedException e) {
95 // silent
96 }
97 }
98 super.dispose();
99 }
100
101 public void setZoom(int zoom) {
102 if (isRenderCompleted())
103 browser.evaluate("map.getView().setZoom(" + zoom + ")");
104 this.zoom = zoom;
105 }
106
107 protected String asVectorSource(List<Node> geoPoints) throws RepositoryException {
108 boolean first = true;
109 StringBuffer sb = new StringBuffer("new ol.source.Vector({ features: [");
110 for (int i = 0; i < geoPoints.size(); i++) {
111 Node node = geoPoints.get(i);
112 if (node.isNodeType(EntityType.geopoint.get())) {
113 if (first)
114 first = false;
115 else
116 sb.append(",");
117 Double lng = node.getProperty(EntityNames.GEO_LONG).getDouble();
118 Double lat = node.getProperty(EntityNames.GEO_LAT).getDouble();
119 sb.append("new ol.Feature({ geometry:");
120 sb.append("new ol.geom.Point(ol.proj.fromLonLat([");
121 sb.append(lng).append(',').append(lat);
122 sb.append("]))");
123 sb.append(",path:\"").append(node.getPath()).append("\"");
124 sb.append(",name:\"").append(node.getName()).append("\"");
125 String entityType = null;
126 if (node.isNodeType(EntityType.local.get())) {
127 entityType = node.getProperty(EntityNames.ENTITY_TYPE).getString();
128 sb.append(", type:'").append(entityType).append("'");
129 }
130 enrichFeature(node, sb);
131 sb.append("})");
132 }
133 }
134 sb.append("]");
135 sb.append(" })");
136 return sb.toString();
137 }
138
139 protected void enrichFeature(Node node, StringBuffer sb) throws RepositoryException {
140
141 }
142
143 public void addPoints(List<Node> geoPoints) throws RepositoryException {
144 this.vectorSource = asVectorSource(geoPoints);
145 if (log.isTraceEnabled())
146 log.trace("Vector source: " + vectorSource);
147 renderVectorSource();
148 }
149
150 public void addPoints(String layerName, List<Node> geoPoints, String style) throws RepositoryException {
151 this.vectorSources.put(layerName, asVectorSource(geoPoints));
152 if (style != null) {
153 layerStyles.put(layerName, style);
154 }
155 renderVectorSources();
156 }
157
158 protected void renderVectorSource() {
159 if (vectorSource == null)
160 return;
161 if (isRenderCompleted()) {
162 // String style = ", style: new ol.style.Style({ image: new ol.style.Icon({ src: '/pkg/org.djapps.on.openheritage.ui/map_oc.png' }) })";
163 String style = vectorSourceStyle != null ? ", style: " + vectorSourceStyle : "";
164 // String style = "";
165 String toEvaluate = "map.addLayer(new ol.layer.Vector({ source: " + vectorSource + style + "}));";
166 // System.out.println(toEvaluate);
167 browser.execute(toEvaluate);
168 }
169 }
170
171 protected void renderVectorSources() {
172 if (vectorSources.isEmpty())
173 return;
174 if (isRenderCompleted()) {
175 StringBuilder toExecute = new StringBuilder();
176 for (String name : vectorSources.keySet()) {
177 String style = layerStyles.containsKey(name) ? ", style: " + layerStyles.get(name) : "";
178 String toEvaluate = "map.addLayer(new ol.layer.Vector({ source: " + vectorSources.get(name) + style
179 + ",name: '" + name + "'}));";
180 toExecute.append(toEvaluate);
181 }
182 if (log.isTraceEnabled())
183 log.trace(toExecute);
184 browser.execute(toExecute.toString());
185 }
186 }
187
188 public void addPoint(Double lng, Double lat) {
189 this.vectorSource = "new ol.source.Vector({ features: [ new ol.Feature({ geometry:"
190 + " new ol.geom.Point(ol.proj.fromLonLat([" + lng + ", " + lat + "])) }) ] })";
191 // if (renderCompleted) {
192 // browser.evaluate(
193 // "map.addLayer(new ol.layer.Vector({ source: new ol.source.Vector({ features: [ new ol.Feature({ geometry:"
194 // + " new ol.geom.Point(ol.proj.fromLonLat([" + lng + ", " + lat + "])) }) ] }) }));");
195 // }
196 renderVectorSource();
197 }
198
199 public void addGpx(String path) {
200 this.gpxSource = "new ol.source.Vector({ url: '" + path + "', format: new ol.format.GPX() })";
201 renderGpxSource();
202 }
203
204 protected void renderGpxSource() {
205 if (gpxSource == null)
206 return;
207 if (isRenderCompleted())
208 browser.evaluate("map.addLayer(new ol.layer.Vector({ source: " + gpxSource + "}));");
209 }
210
211 public void addGeoJson(String path) {
212 String geoJsonSource = "new ol.source.Vector({ url: '" + path + "', format: new ol.format.GeoJSON() })";
213 geoJsonSources.add(geoJsonSource);
214 renderGeoJsonSources();
215 }
216
217 protected void renderGeoJsonSources() {
218 if (geoJsonSources.isEmpty())
219 return;
220 if (isRenderCompleted()) {
221 for (String geoJson : geoJsonSources) {
222 browser.evaluate("map.addLayer(new ol.layer.Vector({ source: " + geoJson + "}));");
223 }
224 }
225 }
226
227 public void setVectorSourceStyle(String vectorSourceStyle) {
228 this.vectorSourceStyle = vectorSourceStyle;
229 }
230
231 private class RenderCompleted extends BrowserFunction {
232
233 RenderCompleted(Browser browser, String name) {
234 super(browser, name);
235 }
236
237 @Override
238 public Object function(Object[] arguments) {
239 try {
240 if (!isRenderCompleted()) {
241 setRenderCompleted(true);
242 if (zoom != null)
243 setZoom(zoom);
244 if (centerLat != null && centerLng != null) {
245 setCenter(centerLng, centerLat);
246 }
247 if (!geoJsonSources.isEmpty())
248 renderGeoJsonSources();
249 if (gpxSource != null)
250 renderGpxSource();
251 if (vectorSource != null)
252 renderVectorSource();
253 if (!vectorSources.isEmpty())
254 renderVectorSources();
255 }
256 return null;
257 } catch (Exception e) {
258 log.error("Cannot render map", e);
259 return null;
260 }
261 }
262 }
263
264 private class OnFeatureSelect extends BrowserFunction {
265
266 OnFeatureSelect(Browser browser, String name) {
267 super(browser, name);
268 }
269
270 @Override
271 public Object function(Object[] arguments) {
272 if (arguments.length == 0)
273 return null;
274 String path = arguments[0].toString();
275 Map<String, Object> properties = new HashMap<>();
276 // properties.put(SuiteEvent.NODE_PATH, path);
277 // properties.put(SuiteEvent.WORKSPACE, CmsConstants.SYS_WORKSPACE);
278 properties.put(SuiteUxEvent.CONTENT_PATH, '/' + CmsConstants.SYS_WORKSPACE + path);
279 cmsView.sendEvent(SuiteUxEvent.refreshPart.topic(), properties);
280 return null;
281 }
282 }
283
284 private class OnFeatureUnselect extends BrowserFunction {
285
286 OnFeatureUnselect(Browser browser, String name) {
287 super(browser, name);
288 }
289
290 @Override
291 public Object function(Object[] arguments) {
292 return null;
293 }
294 }
295
296 private class OnFeatureClick extends BrowserFunction {
297
298 OnFeatureClick(Browser browser, String name) {
299 super(browser, name);
300 }
301
302 @Override
303 public Object function(Object[] arguments) {
304 return null;
305 }
306 }
307 }