split vtm-web into library and vtm-web-app

This commit is contained in:
Hannes Janetzek
2014-03-21 21:42:10 +01:00
parent 1bbf77df0c
commit 4e4d4270db
22 changed files with 296 additions and 71 deletions

View File

@@ -1,29 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<module>
<entry-point class="org.oscim.gdx.client.GwtLauncher" />
<inherits name="com.google.gwt.xml.XML" />
<inherits name="ru.finam.slf4jgwt.logging.gwt.Logging"/>
<set-property name='gwt.logging.enabled' value='TRUE' />
<set-property name='gwt.logging.consoleHandler' value='ENABLED' />
<set-property name='gwt.logging.firebugHandler' value='DISABLED' />
<set-property name='gwt.logging.popupHandler' value='DISABLED' />
<set-property name="gwt.logging.logLevel" value="FINE"/>
<inherits name="GdxMap" />
<inherits name="com.badlogic.gdx.backends.gdx_backends_gwt" />
<inherits name="com.google.gwt.user.theme.chrome.Chrome" />
<!-- super dev mode -->
<add-linker name="xsiframe"/>
<set-configuration-property name='xsiframe.failIfScriptTag' value='FALSE'/>
<set-configuration-property name="devModeRedirectEnabled" value="true"/>
<super-source path="emu" />
<set-configuration-property name="gdx.assetpath" value="./assets" />
<!-- for gradle build, commend out for eclipse build/devmode -->
<set-configuration-property name="gdx.assetoutputpath" value="build/gwt/draftOut" />
<set-property name="user.agent" value="safari"/>
</module>

View File

@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<module>
<!-- <entry-point class="org.oscim.gdx.client.GwtLauncher" /> -->
<inherits name="com.google.gwt.xml.XML" />
<inherits name="ru.finam.slf4jgwt.logging.gwt.Logging" />
<!-- <set-property name='gwt.logging.enabled' value='TRUE' />
<set-property name='gwt.logging.consoleHandler' value='ENABLED' />
<set-property name='gwt.logging.firebugHandler' value='DISABLED' />
<set-property name='gwt.logging.popupHandler' value='DISABLED' />
<set-property name="gwt.logging.logLevel" value="FINE"/>
-->
<inherits name="VtmGdx" />
<!-- <inherits name="com.badlogic.gdx.backends.gdx_backends_gwt" /> -->
<inherits name="com.badlogic.gdx.backends.Gdx" />
<inherits name="com.google.gwt.user.theme.chrome.Chrome" />
<!-- <extend-configuration-property name="gdx.reflect.include" value="com.badlogic.gdx.scenes.scene2d" />
<extend-configuration-property name="gdx.reflect.include" value="com.badlogic.gdx.math" />
<extend-configuration-property name="gdx.reflect.include" value="com.badlogic.gdx.graphics.g2d.TextureRegion" />
<extend-configuration-property name="gdx.reflect.include" value="com.badlogic.gdx.graphics.g2d.BitmapFont" />
<extend-configuration-property name="gdx.reflect.include" value="com.badlogic.gdx.graphics.g2d.NinePatch" />
<extend-configuration-property name="gdx.reflect.include"
value="com.badlogic.gdx.graphics.g3d.materials.MaterialAttribute" />
<extend-configuration-property name="gdx.reflect.include" value="com.badlogic.gdx.graphics.Color" />
<extend-configuration-property name="gdx.reflect.include" value="com.badlogic.gdx.graphics.Texture" />
<extend-configuration-property name="gdx.reflect.include" value="com.badlogic.gdx.utils.Array" />
<extend-configuration-property name="gdx.reflect.include" value="com.badlogic.gdx.utils.ObjectMap" />
<extend-configuration-property name="gdx.reflect.include" value="com.badlogic.gdx.utils.OrderedMap" />
<extend-configuration-property name="gdx.reflect.include" value="com.badlogic.gdx.utils.Disposable" />
<extend-configuration-property name="gdx.reflect.include" value="com.badlogic.gdx.graphics.VertexAttribute" />
<extend-configuration-property name="gdx.reflect.include" value="com.badlogic.gdx.graphics.g3d.model" />
-->
<clear-configuration-property name="gdx.reflect.include" />
<extend-configuration-property name="gdx.reflect.include" value="java.util.List" />
<extend-configuration-property name="gdx.reflect.include" value="java.util.ArrayList" />
<extend-configuration-property name="gdx.reflect.include" value="java.util.Map" />
<extend-configuration-property name="gdx.reflect.include" value="java.util.HashMap" />
<extend-configuration-property name="gdx.reflect.include" value="java.lang.String" />
<extend-configuration-property name="gdx.reflect.include" value="java.lang.Boolean" />
<extend-configuration-property name="gdx.reflect.include" value="java.lang.Byte" />
<extend-configuration-property name="gdx.reflect.include" value="java.lang.Short" />
<extend-configuration-property name="gdx.reflect.include" value="java.lang.Character" />
<extend-configuration-property name="gdx.reflect.include" value="java.lang.Integer" />
<extend-configuration-property name="gdx.reflect.include" value="java.lang.Float" />
<extend-configuration-property name="gdx.reflect.include" value="java.lang.Double" />
<extend-configuration-property name="gdx.reflect.include" value="java.lang.CharSequence" />
<extend-configuration-property name="gdx.reflect.include" value="java.lang.Enum" />
<extend-configuration-property name="gdx.reflect.include" value="java.lang.Object" />
<!-- super dev mode -->
<!--
<add-linker name="xsiframe"/>
<set-configuration-property name='xsiframe.failIfScriptTag' value='FALSE'/>
<set-configuration-property name="devModeRedirectEnabled" value="true"/>
-->
<!-- does not work with super dev mode, include directly in page -->
<!--
<script src="_tessellate.js"/>
<script src="tessellate.js"/>
-->
<public path="resources" />
<super-source path="emu" />
<!-- <set-configuration-property name="gdx.assetpath" value="./assets" /> -->
<!-- for gradle build, commend out for eclipse build/devmode -->
<!-- <set-configuration-property name="gdx.assetoutputpath" value="build/gwt/draftOut" /> -->
<!-- <set-property name="user.agent" value="safari"/> -->
</module>

View File

@@ -47,7 +47,7 @@ public class GwtCanvas implements org.oscim.backend.canvas.Canvas {
GwtPaint p = (GwtPaint) paint;
if (p.stroke && GwtCanvasAdapter.NO_STROKE_TEXT)
if (p.stroke && GwtGdxGraphics.NO_STROKE_TEXT)
return;
Context2d ctx = bitmap.pixmap.getContext();

View File

@@ -26,11 +26,11 @@ import com.google.gwt.canvas.client.Canvas;
import com.google.gwt.canvas.dom.client.Context2d;
import com.google.gwt.canvas.dom.client.TextMetrics;
public class GwtCanvasAdapter extends CanvasAdapter {
public class GwtGdxGraphics extends CanvasAdapter {
public static boolean NO_STROKE_TEXT = false;
public static final GwtCanvasAdapter INSTANCE = new GwtCanvasAdapter();
public static final GwtGdxGraphics INSTANCE = new GwtGdxGraphics();
static final Context2d ctx;
static {
@@ -40,7 +40,7 @@ public class GwtCanvasAdapter extends CanvasAdapter {
ctx = canvas.getContext2d();
}
static synchronized float getTextWidth(String text, String font) {
public static synchronized float getTextWidth(String text, String font) {
ctx.setFont(font);
TextMetrics tm = ctx.measureText(text);
return (float) tm.getWidth();
@@ -72,4 +72,8 @@ public class GwtCanvasAdapter extends CanvasAdapter {
return new GwtCanvas();
}
public static void init() {
g = INSTANCE;
}
}

View File

@@ -1,221 +0,0 @@
/*
* Copyright 2013 Hannes Janetzek
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.oscim.gdx.client;
import java.util.HashMap;
import org.oscim.backend.CanvasAdapter;
import org.oscim.backend.GL20;
import org.oscim.backend.GLAdapter;
import org.oscim.core.MapPosition;
import org.oscim.core.MercatorProjection;
import org.oscim.gdx.GdxMap;
import org.oscim.layers.tile.bitmap.BitmapTileLayer;
import org.oscim.layers.tile.vector.VectorTileLayer;
import org.oscim.layers.tile.vector.labeling.LabelLayer;
import org.oscim.renderer.MapRenderer;
import org.oscim.theme.VtmThemes;
import org.oscim.tiling.TileSource;
import org.oscim.tiling.source.bitmap.BitmapTileSource;
import org.oscim.tiling.source.bitmap.DefaultSources;
import org.oscim.tiling.source.bitmap.DefaultSources.StamenToner;
import org.oscim.tiling.source.oscimap4.OSciMap4TileSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.backends.gwt.GwtApplication;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
class GwtGdxMap extends GdxMap {
static final Logger log = LoggerFactory.getLogger(GwtGdxMap.class);
SearchBox mSearchBox;
@Override
public void create() {
MapConfig c = MapConfig.get();
// stroke text takes about 70% cpu time in firefox:
// https://bug568526.bugzilla.mozilla.org/attachment.cgi?id=447932
// <- circle/stroke test 800ms firefox, 80ms chromium..
// TODO use texture atlas to avoid drawing text-textures
if (GwtApplication.agentInfo().isLinux() && GwtApplication.agentInfo().isFirefox())
GwtCanvasAdapter.NO_STROKE_TEXT = true;
CanvasAdapter.g = GwtCanvasAdapter.INSTANCE;
CanvasAdapter.textScale = 0.7f;
GLAdapter.g = (GL20) Gdx.graphics.getGL20();
GLAdapter.GDX_WEBGL_QUIRKS = true;
MapRenderer.setBackgroundColor(0xffffff);
//Gdx.app.setLogLevel(Application.LOG_DEBUG);
super.create();
double lat = c.getLatitude();
double lon = c.getLongitude();
int zoom = c.getZoom();
float tilt = 0;
float rotation = 0;
String themeName = null;
String mapName = null;
final HashMap<String, String> params = new HashMap<String, String>();
String addOpts = "";
if (Window.Location.getHash() != null) {
String hash = Window.Location.getHash();
hash = hash.substring(1);
String[] urlParams = null;
urlParams = hash.split("&");
if (urlParams.length == 1)
urlParams = hash.split(",");
for (String p : urlParams) {
try {
if (p.startsWith("lat="))
lat = Double.parseDouble(p.substring(4));
else if (p.startsWith("lon="))
lon = Double.parseDouble(p.substring(4));
else if (p.startsWith("scale="))
zoom = Integer.parseInt(p.substring(6));
else if (p.startsWith("rot="))
rotation = Float.parseFloat(p.substring(4));
else if (p.startsWith("tilt="))
tilt = Float.parseFloat(p.substring(5));
else if (p.startsWith("theme="))
themeName = p.substring(6);
else if (p.startsWith("map="))
mapName = p.substring(4);
else {
String[] opt = p.split("=");
if (opt.length > 1)
params.put(opt[0], opt[1]);
else
params.put(opt[0], null);
addOpts += p + "&";
}
} catch (NumberFormatException e) {
}
}
}
final String addParam =
(themeName == null ? "" : ("theme=" + themeName + "&"))
+ (mapName == null ? "" : ("map=" + mapName + "&"))
+ addOpts;
MapPosition p = new MapPosition();
p.setZoomLevel(zoom);
p.setPosition(lat, lon);
p.bearing = rotation;
p.tilt = tilt;
mMap.setMapPosition(p);
VectorTileLayer l = null;
if (c.getBackgroundLayer() != null || mapName != null) {
BitmapTileSource ts;
if ("toner".equals(mapName))
ts = new StamenToner();
else if ("osm".equals(mapName))
ts = new DefaultSources.OpenStreetMap();
else if ("watercolor".equals(mapName))
ts = new DefaultSources.StamenWatercolor();
else if ("arcgis-shaded".equals(mapName))
ts = new DefaultSources.ArcGISWorldShaded();
else if ("imagico".equals(mapName))
ts = new DefaultSources.ImagicoLandcover();
else
ts = new StamenToner();
mMap.setBackgroundMap(new BitmapTileLayer(mMap, ts));
} else {
String url = c.getTileUrl();
TileSource ts = new OSciMap4TileSource(url);
l = mMap.setBaseMap(ts);
if (themeName == null) {
mMap.setTheme(VtmThemes.DEFAULT);
} else {
if ("osmarender".equals(themeName))
mMap.setTheme(VtmThemes.OSMARENDER);
else if ("tron".equals(themeName))
mMap.setTheme(VtmThemes.TRONRENDER);
else if ("newtron".equals(themeName))
mMap.setTheme(VtmThemes.NEWTRON);
else
mMap.setTheme(VtmThemes.DEFAULT);
}
}
if (l != null) {
if (!params.containsKey("nolabel"))
mMap.layers().add(new LabelLayer(mMap, l));
}
mSearchBox = new SearchBox(mMap);
// update URL hash to current position, every 5 seconds
Timer timer = new Timer() {
private int curLon, curLat, curZoom, curTilt, curRot;
private MapPosition pos = new MapPosition();
public void run() {
mMap.viewport().getMapPosition(pos);
int lat = (int) (MercatorProjection.toLatitude(pos.y) * 1000);
int lon = (int) (MercatorProjection.toLongitude(pos.x) * 1000);
int rot = (int) (pos.bearing);
rot = (int) (pos.bearing) % 360;
//rot = rot < 0 ? -rot : rot;
if (curZoom != pos.zoomLevel || curLat != lat || curLon != lon
|| curTilt != rot || curRot != (int) (pos.bearing)) {
curLat = lat;
curLon = lon;
curZoom = pos.zoomLevel;
curTilt = (int) pos.tilt;
curRot = rot;
String newURL = Window.Location
.createUrlBuilder()
.setHash(addParam
+ "scale=" + pos.zoomLevel
+ "&rot=" + curRot
+ "&tilt=" + curTilt
+ "&lat=" + (curLat / 1000f)
+ "&lon=" + (curLon / 1000f))
.buildString();
Window.Location.replace(newURL);
}
}
};
timer.scheduleRepeating(5000);
}
@Override
protected void createLayers() {
}
}

View File

@@ -1,89 +0,0 @@
/*
* Copyright 2013 Hannes Janetzek
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.oscim.gdx.client;
// -draftCompile -localWorkers 2
import org.oscim.core.Tile;
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.backends.gwt.GwtApplication;
import com.badlogic.gdx.backends.gwt.GwtApplicationConfiguration;
import com.badlogic.gdx.backends.gwt.GwtGraphics;
import com.badlogic.gdx.backends.gwt.preloader.Preloader.PreloaderCallback;
import com.badlogic.gdx.backends.gwt.preloader.Preloader.PreloaderState;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.user.client.ui.DockLayoutPanel;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.RootPanel;
public class GwtLauncher extends GwtApplication {
@Override
public GwtApplicationConfiguration getConfig() {
GwtApplicationConfiguration cfg =
new GwtApplicationConfiguration(GwtGraphics.getWindowWidthJSNI(),
GwtGraphics.getWindowHeightJSNI());
DockLayoutPanel p = new DockLayoutPanel(Unit.EM);
p.setHeight("100%");
p.setWidth("100%");
RootPanel.get().add(p);
//HTML header = new HTML("header");
//p.addNorth(header, 2);
//header.setStyleName("header");
//HTML footer = new HTML("footer");
//footer.setStyleName("footer");
//p.addSouth(footer, 2);
cfg.rootPanel = new FlowPanel();
p.add(cfg.rootPanel);
//cfg.antialiasing = true;
cfg.stencil = true;
cfg.fps = 60;
return cfg;
}
@Override
public ApplicationListener getApplicationListener() {
if (GwtGraphics.getDevicePixelRatioJSNI() > 1)
Tile.SIZE = 400;
else
Tile.SIZE = 360;
return new GwtGdxMap();
}
@Override
public PreloaderCallback getPreloaderCallback() {
return new PreloaderCallback() {
@Override
public void update(PreloaderState state) {
}
@Override
public void error(String file) {
//log.debug("error loading " + file);
}
};
}
}

View File

@@ -107,7 +107,7 @@ public class GwtPaint implements Paint {
@Override
public float measureText(String text) {
return GwtCanvasAdapter.getTextWidth(text, font);
return GwtGdxGraphics.getTextWidth(text, font);
}
// FIXME all estimates. no idea how to properly measure canvas text..

View File

@@ -1,52 +0,0 @@
/*
* Copyright 2013 Hannes Janetzek
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.oscim.gdx.client;
import com.google.gwt.core.client.JavaScriptObject;
class MapConfig extends JavaScriptObject {
protected MapConfig() {
}
public static native MapConfig get()/*-{
return $wnd.mapconfig;
}-*/;
public final native double getLatitude() /*-{
return this.latitude;
}-*/;
public final native double getLongitude() /*-{
return this.longitude;
}-*/;
public final native int getZoom() /*-{
return this.zoom;
}-*/;
public final native String getTileSource() /*-{
return this.tilesource;
}-*/;
public final native String getTileUrl() /*-{
return this.tileurl;
}-*/;
public final native String getBackgroundLayer() /*-{
return this.background;
}-*/;
}

View File

@@ -1,366 +0,0 @@
/*
* Copyright 2013 Hannes Janetzek
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.oscim.gdx.client;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.oscim.core.BoundingBox;
import org.oscim.core.GeometryBuffer;
import org.oscim.core.MapPosition;
import org.oscim.layers.PathLayer;
import org.oscim.map.Map;
import com.google.gwt.cell.client.AbstractCell;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.core.client.JsArrayNumber;
import com.google.gwt.dom.client.Style.Visibility;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.FocusEvent;
import com.google.gwt.event.dom.client.FocusHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.http.client.URL;
import com.google.gwt.jsonp.client.JsonpRequestBuilder;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.user.cellview.client.CellList;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.view.client.ProvidesKey;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SingleSelectionModel;
/**
* Entry point classes define <code>onModuleLoad()</code>.
*/
public class SearchBox {
protected static final Logger log = LoggerFactory.getLogger(SearchBox.class);
private static final String NOMINATIM_GLOBAL = "http://nominatim.openstreetmap.org/search?polygon_text=1&addressdetails=0&format=json&limit=25&q=";
interface PoiData {
public static final ProvidesKey<PoiData> KEY_PROVIDER = new ProvidesKey<PoiData>() {
@Override
public Object getKey(PoiData item) {
return item == null ? null : item.getId();
}
};
String getId();
String getName();
double getLatitude();
double getLongitude();
String getIcon();
BoundingBox getBoundingBox();
}
final static class NominatimData extends JavaScriptObject implements
PoiData {
protected NominatimData() {
}
final static class BBox extends JsArrayNumber {
protected BBox() {
}
}
final static class Polygon extends JsArray<JsArrayNumber> {
protected Polygon() {
}
}
@Override
public final native String getId()
/*-{
return this.osm_id;
}-*/;
public final native String name() /*-{
return this.display_name;
}-*/;
public final native BBox getBBox() /*-{
return this.boundingbox
}-*/;
public final native String getWkt() /*-{
return this.geotext;
}-*/;
private final native String latitude() /*-{
return this.lat;
}-*/;
private final native String longitude() /*-{
return this.lon;
}-*/;
public final native String getIcon() /*-{
return this.icon;
}-*/;
@Override
public double getLatitude() {
try {
return Double.parseDouble(latitude());
} catch (Exception e) {
}
return 0;
}
@Override
public double getLongitude() {
try {
return Double.parseDouble(longitude());
} catch (Exception e) {
}
return 0;
}
@Override
public BoundingBox getBoundingBox() {
if (getBBox() != null) {
BBox b = getBBox();
return new BoundingBox(b.get(0), b.get(2), b.get(1), b.get(3));
}
return null;
}
@Override
public String getName() {
String[] n = name().split(", ");
if (n != null && n.length > 2)
return n[0] + ", " + n[1] + " " + n[2];
else if (n != null && n.length > 1)
return n[0] + ", " + n[1];
return name();
}
}
class PoiCell extends AbstractCell<PoiData> {
@Override
public void render(com.google.gwt.cell.client.Cell.Context context,
PoiData value, SafeHtmlBuilder sb) {
// Value can be null, so do a null check..
if (value == null) {
return;
}
sb.appendHtmlConstant("<table>");
if (value.getIcon() != null) {
// Add the contact image.
sb.appendHtmlConstant("<tr><td rowspan='3'>");
sb.appendHtmlConstant("<img border=0 src=" + value.getIcon() + ">");
sb.appendHtmlConstant("</td>");
}
// Add the name and address.
sb.appendHtmlConstant("<td style='font-size:95%;'>");
sb.appendEscaped(value.getName());
sb.appendHtmlConstant("</td></tr>");
//sb.appendEscaped("<tr><td>" + value.getId()+ "</td></tr>");
sb.appendHtmlConstant("</table>");
sb.appendHtmlConstant("<hline>");
}
}
public SearchBox(final Map map) {
final Button searchButton = new Button("Search");
final TextBox searchField = new TextBox();
//searchField.setText("Bremen");
final PathLayer mOverlay = new PathLayer(map, 0xCC0000FF);
map.layers().add(mOverlay);
// We can add style names to widgets
searchButton.addStyleName("sendButton");
RootPanel.get("nameFieldContainer").add(searchField);
RootPanel.get("sendButtonContainer").add(searchButton);
// Focus the cursor on the name field when the app loads
searchField.setFocus(true);
searchField.selectAll();
// Create a cell to render each value in the list.
PoiCell poiCell = new PoiCell();
// Create a CellList that uses the cell.
final CellList<PoiData> cellList = new CellList<PoiData>(poiCell,
PoiData.KEY_PROVIDER);
final SingleSelectionModel<PoiData> selectionModel = new SingleSelectionModel<PoiData>(
PoiData.KEY_PROVIDER);
cellList.setSelectionModel(selectionModel);
final ScrollPanel scroller = new ScrollPanel(cellList);
RootPanel.get("listContainer").add(scroller);
scroller.setSize("350px", "300px");
RootPanel.get("search").getElement().getStyle().setVisibility(Visibility.VISIBLE);
scroller.setVisible(false);
searchField.addFocusHandler(new FocusHandler() {
@Override
public void onFocus(FocusEvent event) {
scroller.setVisible(true);
}
});
selectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
public void onSelectionChange(SelectionChangeEvent event) {
final PoiData d = selectionModel.getSelectedObject();
mOverlay.clearPath();
//log.debug("selected " + d.getName() + " " + d.getLatitude() + " "
// + d.getLongitude());
BoundingBox b = d.getBoundingBox();
if (b != null) {
if (b.maxLatitudeE6 - b.minLatitudeE6 < 100 &&
b.maxLongitudeE6 - b.minLongitudeE6 < 100)
// for small bbox use zoom=16 to get an overview
map.animator().animateTo(500, b.getCenterPoint(), 1 << 16, false);
else
map.animator().animateTo(b);
if (d instanceof NominatimData && ((NominatimData) d).getWkt() != null) {
String wkt = ((NominatimData) d).getWkt();
WKTReader r = new WKTReader();
GeometryBuffer g = new GeometryBuffer(1024, 10);
try {
r.parse(wkt, g);
} catch (Exception e) {
log.debug(wkt);
}
mOverlay.setGeom(g);
//log.debug("add polygon " + p.length());
} else {
mOverlay.addPoint(b.maxLatitudeE6, b.minLongitudeE6);
mOverlay.addPoint(b.maxLatitudeE6, b.maxLongitudeE6);
mOverlay.addPoint(b.minLatitudeE6, b.maxLongitudeE6);
mOverlay.addPoint(b.minLatitudeE6, b.minLongitudeE6);
mOverlay.addPoint(b.maxLatitudeE6, b.minLongitudeE6);
}
// hide overlay after 5 seconds
map.postDelayed(new Runnable() {
@Override
public void run() {
mOverlay.clearPath();
}
}, 5000);
} else {
MapPosition pos = new MapPosition();
map.viewport().setTilt(0);
map.viewport().setRotation(0);
pos.setZoomLevel(13);
pos.setPosition(d.getLatitude(), d.getLongitude());
map.setMapPosition(pos);
}
scroller.setVisible(false);
}
});
// Create a handler for the sendButton and nameField
class MyHandler implements ClickHandler, KeyUpHandler {
/**
* Fired when the user clicks on the sendButton.
*/
public void onClick(ClickEvent event) {
sendRequest();
}
/**
* Fired when the user types in the nameField.
*/
public void onKeyUp(KeyUpEvent event) {
if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
sendRequest();
}
}
/**
* Send the name from the nameField to the server and wait for a
* response.
*/
private void sendRequest() {
String textToServer = searchField.getText();
searchButton.setEnabled(false);
String url = URL
.encode(NOMINATIM_GLOBAL
+ textToServer);
JsonpRequestBuilder builder = new JsonpRequestBuilder();
builder.setCallbackParam("json_callback");
builder.requestObject(url, new AsyncCallback<JsArray<NominatimData>>() {
public void onFailure(Throwable caught) {
log.debug("request failed");
searchButton.setEnabled(true);
}
public void onSuccess(JsArray<NominatimData> data) {
List<PoiData> items = new ArrayList<PoiData>();
for (int i = 0, n = data.length(); i < n; i++) {
NominatimData d = data.get(i);
items.add(d);
}
cellList.setRowCount(items.size(), true);
cellList.setRowData(0, items);
scroller.setVisible(true);
searchButton.setEnabled(true);
}
});
}
}
// Add a handler to send the name to the server
MyHandler handler = new MyHandler();
searchButton.addClickHandler(handler);
searchField.addKeyUpHandler(handler);
}
}

View File

@@ -1,240 +0,0 @@
/*
* Copyright 2013 Hannes Janetzek
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.oscim.gdx.client;
import org.oscim.core.GeometryBuffer;
public class WKTReader {
private final static String POINT = "POINT";
private final static String LINE = "LINESTRING";
private final static String POLY = "POLYGON";
private final static String MULTI = "MULTI";
private final static int SKIP_POINT = POINT.length();
private final static int SKIP_LINE = LINE.length();
private final static int SKIP_POLY = POLY.length();
private final static int SKIP_MULTI = MULTI.length();
public void parse(String wkt, GeometryBuffer geom) throws Exception {
// return position.
int[] pos = new int[] { 0 };
int len = wkt.length();
if (wkt.startsWith(POINT, pos[0])) {
pos[0] += SKIP_POINT;
geom.startPoints();
ensure(wkt, pos, '(');
parsePoint(geom, wkt, len, pos);
ensure(wkt, pos, ')');
} else if (wkt.startsWith(LINE, pos[0])) {
pos[0] += SKIP_LINE;
geom.startLine();
parseLine(geom, wkt, len, pos);
} else if (wkt.startsWith(POLY, pos[0])) {
pos[0] += SKIP_POLY;
geom.startPolygon();
parsePoly(geom, wkt, len, pos);
} else if (wkt.startsWith(MULTI, pos[0])) {
pos[0] += SKIP_MULTI;
if (wkt.startsWith(POINT, pos[0])) {
pos[0] += SKIP_POINT;
geom.startPoints();
ensure(wkt, pos, '(');
parsePoint(geom, wkt, len, pos);
while (wkt.charAt(pos[0]) == ',') {
pos[0]++;
parsePoint(geom, wkt, len, pos);
}
ensure(wkt, pos, ')');
} else if (wkt.startsWith(LINE, pos[0])) {
pos[0] += SKIP_LINE;
geom.startLine();
ensure(wkt, pos, '(');
parseLine(geom, wkt, len, pos);
while (wkt.charAt(pos[0]) == ',') {
pos[0]++;
geom.startLine();
parseLine(geom, wkt, len, pos);
}
ensure(wkt, pos, ')');
} else if (wkt.startsWith(POLY, pos[0])) {
pos[0] += SKIP_POLY;
geom.startPolygon();
ensure(wkt, pos, '(');
parsePoly(geom, wkt, len, pos);
while (wkt.charAt(pos[0]) == ',') {
pos[0]++;
geom.startPolygon();
parsePoly(geom, wkt, len, pos);
}
ensure(wkt, pos, ')');
} else
throw new Exception("usupported geometry ");
} else
throw new Exception("usupported geometry ");
}
private static void ensure(String wkt, int[] pos, char c) throws Exception {
if (wkt.charAt(pos[0]) != c)
throw new Exception();
pos[0]++;
}
private static void parsePoly(GeometryBuffer geom, String wkt, int len, int[] adv)
throws Exception {
// outer ring
ensure(wkt, adv, '(');
parseLine(geom, wkt, len, adv);
while (wkt.charAt(adv[0]) == ',') {
adv[0]++;
geom.startHole();
parseLine(geom, wkt, len, adv);
}
ensure(wkt, adv, ')');
}
private static void parseLine(GeometryBuffer geom, String wkt, int len, int[] adv)
throws Exception {
ensure(wkt, adv, '(');
parsePoint(geom, wkt, len, adv);
while (wkt.charAt(adv[0]) == ',') {
adv[0]++;
parsePoint(geom, wkt, len, adv);
}
ensure(wkt, adv, ')');
}
private static void parsePoint(GeometryBuffer geom, String wkt, int len, int[] adv) {
float x = parseNumber(wkt, len, adv);
// skip ' '
adv[0]++;
float y = parseNumber(wkt, len, adv);
geom.addPoint(x, y);
}
static float parseNumber(String wkt, int len, int[] adv) {
int pos = adv[0];
boolean neg = false;
if (wkt.charAt(pos) == '-') {
neg = true;
pos++;
}
float val = 0;
int pre = 0;
char c = 0;
for (; pos < len; pos++, pre++) {
c = wkt.charAt(pos);
if (c < '0' || c > '9') {
if (pre == 0)
throw new NumberFormatException("s " + c);
break;
}
val = val * 10 + (int) (c - '0');
}
if (pre == 0)
throw new NumberFormatException();
if (c == '.') {
float div = 10;
for (pos++; pos < len; pos++) {
c = wkt.charAt(pos);
if (c < '0' || c > '9')
break;
val = val + ((int) (c - '0')) / div;
div *= 10;
}
}
if (c == 'e' || c == 'E') {
// advance 'e'
pos++;
// check direction
int dir = 1;
if (wkt.charAt(pos) == '-') {
dir = -1;
pos++;
}
// skip leading zeros
for (; pos < len; pos++)
if (wkt.charAt(pos) != '0')
break;
int shift = 0;
for (pre = 0; pos < len; pos++, pre++) {
c = wkt.charAt(pos);
if (c < '0' || c > '9') {
// nothing after 'e'
if (pre == 0)
throw new NumberFormatException("e " + c);
break;
}
shift = shift * 10 + (int) (c - '0');
}
// guess it's ok for sane values of E
if (dir > 0) {
while (shift-- > 0)
val *= 10;
} else {
while (shift-- > 0)
val /= 10;
}
}
adv[0] = pos;
return neg ? -val : val;
}
// public static void main(String[] args) {
// WKTReader r = new WKTReader();
// GeometryBuffer geom = new GeometryBuffer(10, 10);
// try {
// String wkt = "MULTIPOINT(0 0,1 0)";
// r.parse(wkt, geom);
// for (int i = 0; i < geom.index.length; i++) {
// int len = geom.index[i];
// if (len < 0)
// break;
// for (int p = 0; p < len; p += 2)
// System.out.println(len + ": " + geom.points[p] + "," + geom.points[p + 1]);
// }
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
}

View File

@@ -0,0 +1,37 @@
Copyright notice and license for the libtess files (all source files besides
tessellate.[ch] and main.c):
SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice including the dates of first publication and
either this permission notice or a reference to
http://oss.sgi.com/projects/FreeB/
shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Except as contained in this notice, the name of Silicon Graphics, Inc.
shall not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization from
Silicon Graphics, Inc.
--------------------------------------------------------------------------------
Copyright notice for the other files:
SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
Copyright (C) 2013 AT&T Intellectual Property. All Rights Reserved.

View File

@@ -0,0 +1,18 @@
# A minimal, self-contained port of SGI's GLU libtess
Polygon tessellation is a major pain in the neck. Have you ever tried
writing fast and robust code for it? libtess is, to my knowledge, the
only GPL-compatible, liberally-licensed, high-quality polygon
triangulator out there.
This repository includes a self-contained function (tessellate, in
tessellate.c) that you can call to triangulate a polygon that is
potentially self-intersecting, with holes, or with duplicate
vertices. Simple examples of calling the tessellate function directly
are located in main.c.
More interestingly, this repository also includes an
Emscripten-compiled module, _tessellate.js, and a Javascript-friendly
wrapper, in tessellate.js. Simple examples are available under
index.html.

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,107 @@
tessellate = (function() {
Module.TOTAL_MEMORY = 1024 * 1024;
var c_tessellate = Module.cwrap('tessellate', 'void', [ 'number', 'number',
'number', 'number', 'number', 'number' ]);
// special tessellator for extrusion layer - only returns triangle indices
var tessellate = function(vertices, v_start, v_end, boundaries, b_start,
b_end, mode) {
var i;
var v_len = (v_end - v_start);
var b_len = (b_end - b_start);
var p = Module._malloc(v_len * 8);
for (i = 0; i < v_len; ++i)
Module.setValue(p + i * 8, vertices[v_start + i], 'double');
var contours = Module._malloc((b_len + 1) * 4);
// pointer to first contour
Module.setValue(contours + 0, p + 0, 'i32');
var offset = p;
// pointer to further contours + end
for (i = 0; i < b_len; ++i) {
offset += 8 * boundaries[b_start + i];
Module.setValue(contours + 4 * (i + 1), offset, 'i32');
}
var ppcoordinates_out = Module._malloc(4);
var pptris_out = Module._malloc(4);
var pnverts = Module._malloc(4);
var pntris = Module._malloc(4);
c_tessellate(ppcoordinates_out, pnverts, pptris_out, pntris, contours,
contours + 4 * (b_len + 1));
var pcoordinates_out = Module.getValue(ppcoordinates_out, 'i32');
var ptris_out = Module.getValue(pptris_out, 'i32');
var nverts = Module.getValue(pnverts, 'i32');
var ntris = Module.getValue(pntris, 'i32');
var result_triangles = null;
var result_vertices = null;
if (mode){
result_triangles = new Int32Array(ntris * 3);
for (i = 0; i < 3 * ntris; ++i)
result_triangles[i] = Module.getValue(ptris_out + i * 4, 'i32');
result_vertices = new Float32Array(nverts * 2);
for (i = 0; i < 2 * nverts; ++i)
result_vertices[i] = Module.getValue(pcoordinates_out + i * 8, 'double');
} else {
if (nverts * 2 == v_len) {
result_triangles = new Int32Array(ntris * 3);
for (i = 0; i < 3 * ntris; ++i) {
result_triangles[i] = Module.getValue(ptris_out + i * 4, 'i32') * 2;
}
// when a ring has an odd number of points one (or rather two)
// additional vertices will be added. so the following rings
// needs extra offset...
var start = 0;
for ( var j = 0, m = b_len - 1; j < m; j++) {
start += boundaries[b_start + j];
// even number of points?
if (!((boundaries[b_start + j] >> 1) & 1))
continue;
for ( var n = ntris * 3, tri = 0; tri < n; tri++)
if (result_triangles[tri] >= start)
result_triangles[tri] += 2;
start += 2;
}
}
}
Module._free(pnverts);
Module._free(pntris);
Module._free(ppcoordinates_out);
Module._free(pcoordinates_out);
Module._free(pptris_out);
Module._free(ptris_out);
Module._free(p);
Module._free(contours);
if (mode)
return { vertices: result_vertices, triangles: result_triangles };
else
return result_triangles;
};
return tessellate;
})();