]> git.argeo.org Git - gpl/argeo-suite.git/blob - org.argeo.app.ui/src/org/argeo/app/ui/openlayers/OpenLayersMap.java
Use CMS bundle theme.
[gpl/argeo-suite.git] / 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.api.cms.CmsView;
17 import org.argeo.app.api.EntityNames;
18 import org.argeo.app.api.EntityType;
19 import org.argeo.app.ui.SuiteEvent;
20 import org.argeo.api.cms.CmsLog;
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 System.out.println(toExecute);
183 browser.execute(toExecute.toString());
184 }
185 }
186
187 public void addPoint(Double lng, Double lat) {
188 this.vectorSource = "new ol.source.Vector({ features: [ new ol.Feature({ geometry:"
189 + " new ol.geom.Point(ol.proj.fromLonLat([" + lng + ", " + lat + "])) }) ] })";
190 // if (renderCompleted) {
191 // browser.evaluate(
192 // "map.addLayer(new ol.layer.Vector({ source: new ol.source.Vector({ features: [ new ol.Feature({ geometry:"
193 // + " new ol.geom.Point(ol.proj.fromLonLat([" + lng + ", " + lat + "])) }) ] }) }));");
194 // }
195 renderVectorSource();
196 }
197
198 public void addGpx(String path) {
199 this.gpxSource = "new ol.source.Vector({ url: '" + path + "', format: new ol.format.GPX() })";
200 renderGpxSource();
201 }
202
203 protected void renderGpxSource() {
204 if (gpxSource == null)
205 return;
206 if (isRenderCompleted())
207 browser.evaluate("map.addLayer(new ol.layer.Vector({ source: " + gpxSource + "}));");
208 }
209
210 public void addGeoJson(String path) {
211 String geoJsonSource = "new ol.source.Vector({ url: '" + path + "', format: new ol.format.GeoJSON() })";
212 geoJsonSources.add(geoJsonSource);
213 renderGeoJsonSources();
214 }
215
216 protected void renderGeoJsonSources() {
217 if (geoJsonSources.isEmpty())
218 return;
219 if (isRenderCompleted()) {
220 for (String geoJson : geoJsonSources) {
221 browser.evaluate("map.addLayer(new ol.layer.Vector({ source: " + geoJson + "}));");
222 }
223 }
224 }
225
226 public void setVectorSourceStyle(String vectorSourceStyle) {
227 this.vectorSourceStyle = vectorSourceStyle;
228 }
229
230 private class RenderCompleted extends BrowserFunction {
231
232 RenderCompleted(Browser browser, String name) {
233 super(browser, name);
234 }
235
236 @Override
237 public Object function(Object[] arguments) {
238 try {
239 if (!isRenderCompleted()) {
240 setRenderCompleted(true);
241 if (zoom != null)
242 setZoom(zoom);
243 if (centerLat != null && centerLng != null) {
244 setCenter(centerLng, centerLat);
245 }
246 if (!geoJsonSources.isEmpty())
247 renderGeoJsonSources();
248 if (gpxSource != null)
249 renderGpxSource();
250 if (vectorSource != null)
251 renderVectorSource();
252 if (!vectorSources.isEmpty())
253 renderVectorSources();
254 }
255 return null;
256 } catch (Exception e) {
257 log.error("Cannot render map", e);
258 return null;
259 }
260 }
261 }
262
263 private class OnFeatureSelect extends BrowserFunction {
264
265 OnFeatureSelect(Browser browser, String name) {
266 super(browser, name);
267 }
268
269 @Override
270 public Object function(Object[] arguments) {
271 if (arguments.length == 0)
272 return null;
273 String path = arguments[0].toString();
274 Map<String, Object> properties = new HashMap<>();
275 properties.put(SuiteEvent.NODE_PATH, path);
276 properties.put(SuiteEvent.WORKSPACE, CmsConstants.SYS_WORKSPACE);
277 cmsView.sendEvent(SuiteEvent.refreshPart.topic(), properties);
278 return null;
279 }
280 }
281
282 private class OnFeatureUnselect extends BrowserFunction {
283
284 OnFeatureUnselect(Browser browser, String name) {
285 super(browser, name);
286 }
287
288 @Override
289 public Object function(Object[] arguments) {
290 return null;
291 }
292 }
293
294 private class OnFeatureClick extends BrowserFunction {
295
296 OnFeatureClick(Browser browser, String name) {
297 super(browser, name);
298 }
299
300 @Override
301 public Object function(Object[] arguments) {
302 return null;
303 }
304 }
305 }