]> git.argeo.org Git - gpl/argeo-suite.git/blob - environment/org.argeo.geo.ui/src/org/argeo/support/openlayers/OpenLayersMap.java
Improve logging.
[gpl/argeo-suite.git] / environment / org.argeo.geo.ui / src / org / argeo / support / openlayers / OpenLayersMap.java
1 package org.argeo.support.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.apache.commons.logging.Log;
17 import org.apache.commons.logging.LogFactory;
18 import org.argeo.api.NodeConstants;
19 import org.argeo.cms.ui.CmsView;
20 import org.argeo.cms.ui.util.CmsUiUtils;
21 import org.argeo.entity.EntityNames;
22 import org.argeo.entity.EntityType;
23 import org.argeo.suite.ui.SuiteEvent;
24 import org.eclipse.swt.SWT;
25 import org.eclipse.swt.browser.Browser;
26 import org.eclipse.swt.browser.BrowserFunction;
27 import org.eclipse.swt.layout.GridLayout;
28 import org.eclipse.swt.widgets.Composite;
29
30 /** Display a map. */
31 public class OpenLayersMap extends Composite {
32 private static final long serialVersionUID = 1055893020490283622L;
33
34 private final static Log log = LogFactory.getLog(OpenLayersMap.class);
35
36 private Browser browser;
37 private boolean renderCompleted = false;
38
39 private Double centerLng = null, centerLat = null;
40 private Integer zoom = null;
41 private String vectorSource = null;
42 private String gpxSource = null;
43
44 private List<String> geoJsonSources = new ArrayList<>();
45
46 private CmsView cmsView;
47
48 public OpenLayersMap(Composite parent, int style, URL mapHtml) {
49 super(parent, style);
50 cmsView = CmsView.getCmsView(parent);
51 setLayout(new GridLayout());
52
53 browser = new Browser(this, SWT.BORDER);
54 browser.setLayoutData(CmsUiUtils.fillAll());
55 String html;
56 try (InputStream in = mapHtml.openStream()) {
57 html = IOUtils.toString(in, StandardCharsets.UTF_8);
58 } catch (IOException e) {
59 throw new RuntimeException(e);
60 }
61 new RenderCompleted(browser, "renderCompleted");
62 new OnFeatureSelect(browser, "onFeatureSelect");
63 new OnFeatureUnselect(browser, "onFeatureUnselect");
64 new OnFeatureClick(browser, "onFeatureClick");
65 browser.setText(html);
66 }
67
68 public void setCenter(Double lng, Double lat) {
69 if (isRenderCompleted())
70 browser.evaluate("map.getView().setCenter(ol.proj.fromLonLat([" + lng + ", " + lat + "]))");
71 this.centerLat = lat;
72 this.centerLng = lng;
73 }
74
75 public synchronized void setRenderCompleted(boolean renderCompleted) {
76 this.renderCompleted = renderCompleted;
77 notifyAll();
78 }
79
80 public synchronized boolean isRenderCompleted() {
81 return renderCompleted;
82 }
83
84 @Override
85 public synchronized void dispose() {
86 long timeout = 500;
87 long begin = System.currentTimeMillis();
88 while (!isRenderCompleted() && ((System.currentTimeMillis() - begin) < timeout)) {
89 try {
90 wait(50);
91 } catch (InterruptedException e) {
92 // silent
93 }
94 }
95 super.dispose();
96 }
97
98 public void setZoom(int zoom) {
99 if (isRenderCompleted())
100 browser.evaluate("map.getView().setZoom(" + zoom + ")");
101 this.zoom = zoom;
102 }
103
104 public void addPoints(List<Node> geoPoints) throws RepositoryException {
105 boolean first = true;
106 StringBuffer sb = new StringBuffer("new ol.source.Vector({ features: [");
107 for (int i = 0; i < geoPoints.size(); i++) {
108 Node node = geoPoints.get(i);
109 if (node.isNodeType(EntityType.geopoint.get())) {
110 if (first)
111 first = false;
112 else
113 sb.append(",");
114 Double lng = node.getProperty(EntityNames.GEO_LONG).getDouble();
115 Double lat = node.getProperty(EntityNames.GEO_LAT).getDouble();
116 sb.append("new ol.Feature({ geometry:");
117 sb.append("new ol.geom.Point(ol.proj.fromLonLat([");
118 sb.append(lng).append(',').append(lat);
119 sb.append("]))");
120 sb.append(",path:'").append(node.getPath()).append("'");
121 sb.append("})");
122 }
123 }
124 sb.append("] })");
125 this.vectorSource = sb.toString();
126 if (log.isTraceEnabled())
127 log.trace("Vector source: " + vectorSource);
128 renderVectorSource();
129 }
130
131 protected void renderVectorSource() {
132 if (vectorSource == null)
133 return;
134 if (isRenderCompleted())
135 browser.evaluate("map.addLayer(new ol.layer.Vector({ source: " + vectorSource + "}));");
136 }
137
138 public void addPoint(Double lng, Double lat) {
139 this.vectorSource = "new ol.source.Vector({ features: [ new ol.Feature({ geometry:"
140 + " new ol.geom.Point(ol.proj.fromLonLat([" + lng + ", " + lat + "])) }) ] })";
141 // if (renderCompleted) {
142 // browser.evaluate(
143 // "map.addLayer(new ol.layer.Vector({ source: new ol.source.Vector({ features: [ new ol.Feature({ geometry:"
144 // + " new ol.geom.Point(ol.proj.fromLonLat([" + lng + ", " + lat + "])) }) ] }) }));");
145 // }
146 renderVectorSource();
147 }
148
149 public void addGpx(String path) {
150 this.gpxSource = "new ol.source.Vector({ url: '" + path + "', format: new ol.format.GPX() })";
151 renderGpxSource();
152 }
153
154 protected void renderGpxSource() {
155 if (gpxSource == null)
156 return;
157 if (isRenderCompleted())
158 browser.evaluate("map.addLayer(new ol.layer.Vector({ source: " + gpxSource + "}));");
159 }
160
161 public void addGeoJson(String path) {
162 String geoJsonSource = "new ol.source.Vector({ url: '" + path + "', format: new ol.format.GeoJSON() })";
163 geoJsonSources.add(geoJsonSource);
164 renderGeoJsonSources();
165 }
166
167 protected void renderGeoJsonSources() {
168 if (geoJsonSources.isEmpty())
169 return;
170 if (isRenderCompleted()) {
171 for (String geoJson : geoJsonSources) {
172 browser.evaluate("map.addLayer(new ol.layer.Vector({ source: " + geoJson + "}));");
173 }
174 }
175 }
176
177 private class RenderCompleted extends BrowserFunction {
178
179 RenderCompleted(Browser browser, String name) {
180 super(browser, name);
181 }
182
183 @Override
184 public Object function(Object[] arguments) {
185 try {
186 if (!isRenderCompleted()) {
187 setRenderCompleted(true);
188 if (zoom != null)
189 setZoom(zoom);
190 if (centerLat != null && centerLng != null) {
191 setCenter(centerLng, centerLat);
192 }
193 if (vectorSource != null)
194 renderVectorSource();
195 if (gpxSource != null)
196 renderGpxSource();
197 if (!geoJsonSources.isEmpty())
198 renderGeoJsonSources();
199 }
200 return null;
201 } catch (Exception e) {
202 log.error("Cannot render map", e);
203 return null;
204 }
205 }
206 }
207
208 private class OnFeatureSelect extends BrowserFunction {
209
210 OnFeatureSelect(Browser browser, String name) {
211 super(browser, name);
212 }
213
214 @Override
215 public Object function(Object[] arguments) {
216 if (arguments.length == 0)
217 return null;
218 String path = arguments[0].toString();
219 Map<String, Object> properties = new HashMap<>();
220 properties.put(SuiteEvent.NODE_PATH, path);
221 properties.put(SuiteEvent.WORKSPACE, NodeConstants.SYS_WORKSPACE);
222 cmsView.sendEvent(SuiteEvent.refreshPart.topic(), properties);
223 return null;
224 }
225 }
226
227 private class OnFeatureUnselect extends BrowserFunction {
228
229 OnFeatureUnselect(Browser browser, String name) {
230 super(browser, name);
231 }
232
233 @Override
234 public Object function(Object[] arguments) {
235 return null;
236 }
237 }
238
239 private class OnFeatureClick extends BrowserFunction {
240
241 OnFeatureClick(Browser browser, String name) {
242 super(browser, name);
243 }
244
245 @Override
246 public Object function(Object[] arguments) {
247 return null;
248 }
249 }
250 }