*******************************************************************************/
package org.simantics.maps.eclipse;
+import java.awt.geom.AffineTransform;
+
import org.simantics.g2d.canvas.Hints;
import org.simantics.g2d.canvas.ICanvasContext;
import org.simantics.g2d.canvas.impl.AbstractCanvasParticipant;
protected MapNode node = null;
protected MapScaleNode scaleNode = null;
- private int scale;
+ private AffineTransform transform;
- public MapPainter(int scale) {
- this.scale = scale;
+ public MapPainter(AffineTransform transform) {
+ this.transform = transform;
}
@Override
@SGInit
public void initSG(G2DParentNode parent) {
node = parent.addNode("map", MapNode.class);
- node.setScale(scale);
+ node.setTransform(transform);
node.setEnabled(true);
node.setZIndex(Integer.MIN_VALUE + 999); // Just under the grid
scaleNode = parent.addNode("mapScale", MapScaleNode.class);
- scaleNode.setScale(scale);
+ scaleNode.setTransform(transform);
scaleNode.setEnabled(true);
scaleNode.setZIndex(Integer.MAX_VALUE - 999); // Just under the grid
}
package org.simantics.maps.prefs;
+import java.util.Arrays;
+import java.util.List;
+
import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
-import org.eclipse.core.runtime.preferences.DefaultScope;
+import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;
public class MapsClientPreferenceInitializer extends AbstractPreferenceInitializer {
@Override
public void initializeDefaultPreferences() {
- Preferences node = DefaultScope.INSTANCE.getNode(MapsClientPreferences.P_NODE);
- node.put(MapsClientPreferences.P_TILESERVER_URL, "http://localhost:8088");
+ Preferences node = MapsClientPreferences.getPreferences();
+
+ try {
+ String[] keys = node.keys();
+ List<String> keyss = Arrays.asList(keys);
+ if (!keyss.contains(MapsClientPreferences.P_TILESERVER_URL) && node.get(MapsClientPreferences.P_TILESERVER_URL, "").isEmpty()) {
+ String possibleBuiltin = MapsClientPreferences.possibleBuiltinServerURL();
+ if (possibleBuiltin == null)
+ possibleBuiltin = "";
+ node.put(MapsClientPreferences.P_TILESERVER_URL, possibleBuiltin);
+ }
+ } catch (BackingStoreException e) {
+ e.printStackTrace();
+ }
}
}
package org.simantics.maps.prefs;
import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.jface.preference.BooleanFieldEditor;
import org.eclipse.jface.preference.FieldEditor;
import org.eclipse.jface.preference.FieldEditorPreferencePage;
import org.eclipse.jface.preference.IPreferenceStore;
@Override
protected void createFieldEditors() {
FieldEditor editor = new StringFieldEditor(MapsClientPreferences.P_TILESERVER_URL, "Tileserver URL", getFieldEditorParent());
- editor.setPreferenceStore(getPreferenceStore());
addField(editor);
+
+ BooleanFieldEditor beditor = new BooleanFieldEditor(MapsClientPreferences.P_USE_BUILTIN, "Use builtin server", getFieldEditorParent());
+ addField(beditor);
+ }
+
+ @Override
+ protected void performApply() {
}
}
package org.simantics.maps.prefs;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.osgi.service.prefs.Preferences;
+
public class MapsClientPreferences {
public static final String P_NODE = "org.simantics.district.maps";
public static final String P_TILESERVER_URL = "org.simantics.district.maps.prefs.tileserverURL";
+ public static final String P_USE_BUILTIN = "org.simantics.district.maps.prefs.tileserverURL";
+
+ // TODO: fix this, currently copied from MapsServerPreferences
+ public static final String P_DEFAULT_PORT = "org.simantics.maps.server.defaultPort";
+ public static final String P_CURRENT_TM2STYLE = "org.simantics.maps.server.currentTM2Style";
+ public static final String P_SERVER_NODE = "org.simantics.maps.server";
+ public static Preferences getServerPreferences() {
+ return InstanceScope.INSTANCE.getNode(P_SERVER_NODE);
+ }
+
+ public static Preferences getPreferences() {
+ return InstanceScope.INSTANCE.getNode(P_NODE);
+ }
+
+ public static String tileserverURL() {
+ return getPreferences().get(P_TILESERVER_URL, "");
+ }
+
+ public static boolean useBuiltinServer() {
+ return getPreferences().getBoolean(P_USE_BUILTIN, true);
+ }
+
+ public static String possibleBuiltinServerURL() {
+ int port = getServerPreferences().getInt(P_DEFAULT_PORT, -1);
+ String style = getServerPreferences().get(P_CURRENT_TM2STYLE, null);
+ if (port != -1 && style != null) {
+ try {
+ return new URL("http", "localhost", port, "/" + style).toString();
+ } catch (MalformedURLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ return null;
+ }
+
}
import org.simantics.maps.WebService;
import org.simantics.maps.osm.OSMTileProvider;
import org.simantics.maps.pojo.TileJobQueue;
+import org.simantics.maps.prefs.MapsClientPreferences;
import org.simantics.maps.tile.IFilter;
import org.simantics.maps.tile.ITileJobQueue;
import org.simantics.maps.tile.ITileListener;
}
};
- private int scale;
-
public void init() {
+ // Construct WebService from client properties
+ String url;
+ if (MapsClientPreferences.useBuiltinServer())
+ url = MapsClientPreferences.possibleBuiltinServerURL();
+ else
+ url = MapsClientPreferences.tileserverURL();
+ if (!url.endsWith("/"))
+ url = url + "/";
+
try {
- ITileProvider provider = new OSMTileProvider(new WebService("http://localhost:8080/mapbox-studio-osm-bright.tm2/"), TILE_PIXEL_SIZE);
+ ITileProvider provider = new OSMTileProvider(new WebService(url), TILE_PIXEL_SIZE);
// Try to load eclipse specific implementation of TileJobQueue, if it doesn't exist, fall back to pojo implementation
try {
if (!enabled)
return;
- Graphics2D g = (Graphics2D)g2d.create();
- AffineTransform tr = (AffineTransform)g.getTransform().clone();
+ AffineTransform ot = g2d.getTransform();
+ g2d.transform(transform);
+
+ AffineTransform tr = g2d.getTransform();
+
+// Graphics2D g = (Graphics2D)g2d.create();
+// AffineTransform tr = (AffineTransform)g.getTransform().clone();
double scaleX = Math.abs(tr.getScaleX());
double scaleY = Math.abs(tr.getScaleY());
double offsetX = -tr.getTranslateX();
double offsetY = -tr.getTranslateY();
- g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
Rectangle2D sp = localToControl(new Rectangle2D.Double(0.0, 0.0, 1.0, 1.0));
- Rectangle2D b = (Rectangle2D)((Rectangle)g.getRenderingHint(G2DRenderingHints.KEY_CONTROL_BOUNDS)).getBounds2D(); // getClipBounds is not accurate enough, use original clipbounds and scale here
+ Rectangle2D b = (Rectangle2D)((Rectangle)g2d.getRenderingHint(G2DRenderingHints.KEY_CONTROL_BOUNDS)).getBounds2D(); // getClipBounds is not accurate enough, use original clipbounds and scale here
Rectangle2D viewbox = new Rectangle2D.Double(offsetX/scaleX, offsetY/scaleY, b.getWidth()/sp.getWidth(), b.getHeight()/sp.getHeight()); //g.getClipBounds();
if(viewbox == null) return; // FIXME
double smallerViewboxDimension = viewbox.getWidth() < viewbox.getHeight() ? viewbox.getWidth() * MAP_SCALE : viewbox.getHeight() * MAP_SCALE;
int level = 0;
- double tileSize = get360Scaled() * MAP_SCALE*2;
+ double tileSize = 360 * MAP_SCALE*2;
while (level < MAX_TILE_LEVEL) {
double ratio = smallerViewboxDimension / tileSize;
if (ratio >= 0.85) {
tileSize *= 0.5;
level++;
}
- System.out.println("level " + level);
/*
* To convert y-coordinates to map coordinates in ruler, use:
* double val = (y-offsetY)/scaleY;
* String str = formatValue(val);
*/
- double minx = Math.min(get180Scaled(), Math.max(viewbox.getMinX(), -get180Scaled()));
- double maxx = Math.min(get180Scaled(), Math.max(viewbox.getMaxX(), -get180Scaled()));
+ double minx = Math.min(180, Math.max(viewbox.getMinX(), -180));
+ double maxx = Math.min(180, Math.max(viewbox.getMaxX(), -180));
- double miny = Math.min(get360Scaled(), Math.max(viewbox.getMinY()+get180Scaled(), 0));
- double maxy = Math.min(get360Scaled(), Math.max(viewbox.getMaxY()+get180Scaled(), 0));
+ double miny = Math.min(360, Math.max(viewbox.getMinY()+180, 0));
+ double maxy = Math.min(360, Math.max(viewbox.getMaxY()+180, 0));
- g.setTransform(new AffineTransform());
- g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
+ g2d.setTransform(new AffineTransform());
+ g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
int levels = (1 << level);
// http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
- int left = (int)Math.floor( (minx + get180Scaled()) / get360Scaled() * (1<<level) );
- int right = (int)Math.floor( (maxx + get180Scaled()) / get360Scaled() * (1<<level) );
- int top = (int)Math.floor(miny / get360Scaled() * (1<<level));// (int)Math.floor( (1 - Math.log(Math.tan(Math.toRadians(miny)) + 1 / Math.cos(Math.toRadians(miny))) / Math.PI) / 2 * (1<<level) );
- int bottom = (int)Math.floor(maxy / get360Scaled() * (1<<level));// (int)Math.floor( (1 - Math.log(Math.tan(Math.toRadians(maxy)) + 1 / Math.cos(Math.toRadians(maxy))) / Math.PI) / 2 * (1<<level) );
+ int left = (int)Math.floor( (minx + 180) / 360 * (1<<level) );
+ int right = (int)Math.floor( (maxx + 180) / 360 * (1<<level) );
+ int top = (int)Math.floor(miny / 360 * (1<<level));// (int)Math.floor( (1 - Math.log(Math.tan(Math.toRadians(miny)) + 1 / Math.cos(Math.toRadians(miny))) / Math.PI) / 2 * (1<<level) );
+ int bottom = (int)Math.floor(maxy / 360 * (1<<level));// (int)Math.floor( (1 - Math.log(Math.tan(Math.toRadians(maxy)) + 1 / Math.cos(Math.toRadians(maxy))) / Math.PI) / 2 * (1<<level) );
- double tsx = get360Scaled() / (double)levels; // Size of tile on zoom level
+ double tsx = 360 / (double)levels; // Size of tile on zoom level
for(int tx = left; tx <= right; tx++) {
if(tx < 0 || tx >= levels) continue;
for(int ty = top; ty <= bottom; ty++) {
if(ty < 0 || ty >= levels) continue;
TileKey tile = new TileKey(level, tx, ty);
double y = (double)ty - (double)levels/2; // In level 0 we have only one tile
- paintTile(tileCache, g, tr, tile, tx*tsx-get180Scaled(), y*tsx, tsx);
+ paintTile(tileCache, g2d, tr, tile, tx*tsx-180, y*tsx, tsx);
}
}
- g.dispose();
+// g.dispose();
// Check if transform has changed
transformChanged(tr, level);
- }
-
- private double get360Scaled() {
- return 360 * scale;
- }
-
- private double get180Scaled() {
- return 180 * scale;
+
+ g2d.setTransform(ot);
}
@Override
repaint();
}
- public void setScale(int scale) {
- this.scale = scale;
- }
-
}
\ No newline at end of file
protected double gridSize = 1.0;
- private double scale;
-
@Override
public void render(Graphics2D g) {
if (!enabled)
return;
+ AffineTransform ot = g.getTransform();
+ g.transform(transform);
+
AffineTransform tr = g.getTransform();
double scaleX = Math.abs(tr.getScaleX());
double scaleY = Math.abs(tr.getScaleY());
label += stepX;
}
- g.setTransform(tr);
+ g.setTransform(ot);
}
@Override
this.enabled = enabled;
}
- public void setScale(double scale) {
- this.scale = scale;
- }
-
@Override
public void init() {
try {
}
public double getMeterPerPixel(double screenX, double screenY, double scaleX, double scaleY) {
- double startLon = (screenX / scaleX) / scale;
- double val = (screenY / scaleY) / scale;
+ double startLon = (screenX / scaleX);
+ double val = (screenY / scaleY);
val = Math.toDegrees(Math.atan(Math.sinh(Math.toRadians(val))));
double startLat = val;
- double endLon = ((screenX + 1) / scaleX) / scale;
+ double endLon = ((screenX + 1) / scaleX);
double endLat = val;
calculator.setStartingGeographicPoint(startLon, startLat);
import org.simantics.g2d.participant.GridPainter;
import org.simantics.g2d.participant.PanZoomRotateHandler;
import org.simantics.g2d.participant.RenderingQualityInteractor;
+import org.simantics.maps.MapScalingTransform;
import org.simantics.maps.eclipse.MapPainter;
import org.simantics.modeling.ui.diagramEditor.DiagramViewer;
import org.simantics.utils.datastructures.hints.IHintContext;
ctx.add(new ElementPainter());
ctx.add(new DNPointerInteractor());
- ctx.add(new MapPainter(100000));
+ ctx.add(new MapPainter(MapScalingTransform.INSTANCE));
- ctx.add(new NetworkDrawingParticipant());
+ ctx.add(new NetworkDrawingParticipant(MapScalingTransform.INSTANCE));
}
protected String getPopupId() {
package org.simantics.district.network.ui;
-import java.awt.geom.Path2D;
import java.awt.geom.Point2D;
-import java.awt.geom.Point2D.Double;
-import java.awt.geom.Rectangle2D;
public class DistrictNetworkEdge {
- private Path2D path;
+ private Point2D startPoint;
+ private Point2D endPoint;
- public DistrictNetworkEdge(Path2D path) {
- this.path = path;
+ public DistrictNetworkEdge(Point2D startPoint, Point2D endPoint) {
+ this.startPoint = startPoint;
+ this.endPoint = endPoint;
}
- public Path2D getPath() {
- return path;
+ public Point2D getStartPoint() {
+ return startPoint;
}
- public Rectangle2D getBounds(Rectangle2D rect) {
- rect.setFrame(path.getBounds2D());
- return rect;
+ public Point2D getEndPoint() {
+ return endPoint;
}
}
package org.simantics.district.network.ui;
+import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;
import org.simantics.g2d.diagram.handler.PickRequest;
import org.simantics.g2d.diagram.participant.AbstractDiagramParticipant;
import org.simantics.g2d.element.IElement;
+import org.simantics.maps.MapScalingTransform;
import org.simantics.scenegraph.g2d.G2DNode;
import org.simantics.scenegraph.g2d.G2DParentNode;
import org.simantics.utils.datastructures.hints.IHintContext.Key;
public static final double PICK_DIST = 10;
private NetworkDrawingNode node;
+
+ private AffineTransform transform;
+ public NetworkDrawingParticipant(AffineTransform transform) {
+ this.transform = transform;
+ }
+
@SGInit
public void initSG(G2DParentNode parent) {
node = parent.addNode("networkDrawingNode", NetworkDrawingNode.class);
+ node.setTransform(transform);
node.setNetworkDrawingParticipant(this);
}
node.setColor(ElementUtils.getAdditionalColor(edgeElement, Color.BLUE));
node.setDNEdge(edge);
+ AffineTransform at = ElementUtils.getTransform(edgeElement);
+ if (at != null)
+ node.setTransform(at);
}
}
if (size == null)
size = new Rectangle2D.Double();
if (edge != null)
- edge.getBounds(size);
+ size.setFrame(DistrictNetworkEdgeNode.calculatePath(edge).getBounds2D());
else
LOGGER.debug("Element {} does not have edge!", e);
package org.simantics.district.network.ui.adapters;
-import java.awt.geom.Path2D;
import java.awt.geom.Point2D;
import org.simantics.db.AsyncReadGraph;
import org.simantics.diagram.synchronization.SynchronizationHints;
import org.simantics.diagram.synchronization.graph.GraphSynchronizationHints;
import org.simantics.diagram.synchronization.graph.layer.GraphLayerManager;
-import org.simantics.district.network.ModelledCRS;
import org.simantics.district.network.ontology.DistrictNetworkResource;
import org.simantics.district.network.ui.DistrictNetworkEdge;
import org.simantics.g2d.canvas.ICanvasContext;
Resource startVertex = graph.getSingleObject(edgeResource, DN.HasStartVertex);
Resource endVertex = graph.getSingleObject(edgeResource, DN.HasEndVertex);
- // TODO: fix scale..
- double scale = 100000;
-
+ // TODO: Find maybe a better way to apply the scaling
double[] startCoords = graph.getRelatedValue2(startVertex, DIA.HasLocation);
-
- double startLon = ModelledCRS.longitudeToX(startCoords[0]) * scale;
- double startLat = ModelledCRS.latitudeToY(startCoords[1]) * scale;
-
double[] endCoords = graph.getRelatedValue2(endVertex, DIA.HasLocation);
-
- double endLon = ModelledCRS.longitudeToX(endCoords[0]) * scale;
- double endLat = ModelledCRS.latitudeToY(endCoords[1]) * scale;
-
- Path2D path = new Path2D.Double();
- path.moveTo(startLon, startLat);
- path.lineTo(endLon, endLat);
-
- DistrictNetworkEdge edge = new DistrictNetworkEdge(path);
+ DistrictNetworkEdge edge = new DistrictNetworkEdge(new Point2D.Double(startCoords[0], startCoords[1]), new Point2D.Double(endCoords[0], endCoords[1]));
Resource mapping = graph.getSingleObject(edgeResource, DistrictNetworkResource.getInstance(graph).HasMapping);
element.setHint(DistrictNetworkAdditionalColor.KEY_DN_MAPPING_RESOURCE, mapping);
element.setHint(DistrictNetworkEdgeElement.KEY_DN_EDGE, edge);
+ // set scaling transform
+ ElementUtils.setTransform(element, MapScalingTransform.INSTANCE);
+
IModifiableSynchronizationContext context = diagram.getHint(SynchronizationHints.CONTEXT);
GraphLayerManager layerManager = context.get(GraphSynchronizationHints.GRAPH_LAYER_MANAGER);
@Override
public Rectangle2D getBounds(IElement e, Rectangle2D size) {
DistrictNetworkVertexNode node = e.getHint(KEY_DN_VERTEX_NODE);
- size.setFrame(node.getBoundsInLocal());
+ Rectangle2D boundsInLocal = node.getBoundsInLocal();
+ size.setFrame(boundsInLocal);
return size;
}
package org.simantics.district.network.ui.adapters;
-import java.awt.geom.AffineTransform;
-
import org.simantics.db.AsyncReadGraph;
import org.simantics.db.ReadGraph;
import org.simantics.db.Resource;
import org.simantics.diagram.synchronization.SynchronizationHints;
import org.simantics.diagram.synchronization.graph.GraphSynchronizationHints;
import org.simantics.diagram.synchronization.graph.layer.GraphLayerManager;
-import org.simantics.district.network.ModelledCRS;
import org.simantics.district.network.ontology.DistrictNetworkResource;
import org.simantics.g2d.canvas.ICanvasContext;
import org.simantics.g2d.diagram.DiagramHints;
import org.simantics.g2d.element.IElement;
import org.simantics.g2d.element.handler.impl.StaticObjectAdapter;
import org.simantics.g2d.layers.ILayersEditor;
+import org.simantics.maps.MapScalingTransform;
public class DistrictNetworkVertexElementFactory extends SyncElementFactory {
element.setHint(DistrictNetworkAdditionalColor.KEY_DN_MAPPING_RESOURCE, mapping);
element.setHint(DistrictNetworkVertexElement.KEY_DN_VERTEX, vertex);
- // TODO: set element transform based on layer SRS and coords
-
- double x = ModelledCRS.longitudeToX(coords[0]);
- double y = ModelledCRS.latitudeToY(coords[1]);
-
- double scale = 100000;
-
- AffineTransform at = new AffineTransform(1, 0, 0, 1, x * scale, y * scale);
- ElementUtils.setTransform(element, at);
+ // set scaling transform for vertices
+ ElementUtils.setTransform(element, MapScalingTransform.INSTANCE);
IModifiableSynchronizationContext context = diagram.getHint(SynchronizationHints.CONTEXT);
GraphLayerManager layerManager = context.get(GraphSynchronizationHints.GRAPH_LAYER_MANAGER);
import java.awt.geom.Rectangle2D;
import org.simantics.district.network.ModelledCRS;
-import org.simantics.district.network.ontology.DistrictNetworkResource;
import org.simantics.district.network.ui.DistrictNetworkEdge;
import org.simantics.scenegraph.g2d.G2DNode;
import org.simantics.scenegraph.utils.GeometryUtils;
g2d.setStroke(STROKE);
}
}
- // render
- g2d.draw(edge.getPath());
+ g2d.draw(calculatePath(edge));
+
// Reset
g2d.setStroke(oldStroke);
g2d.setColor(oldColor);
g2d.setTransform(ot);
}
+ public static Path2D calculatePath(DistrictNetworkEdge edge) {
+ // Convert to screen coordinates
+ double startX = ModelledCRS.longitudeToX(edge.getStartPoint().getX());
+ double startY = ModelledCRS.latitudeToY(edge.getStartPoint().getY());
+ double endX = ModelledCRS.longitudeToX(edge.getEndPoint().getX());
+ double endY = ModelledCRS.latitudeToY(edge.getEndPoint().getY());
+
+ // render
+ Path2D path = new Path2D.Double();
+ path.moveTo(startX, startY);
+ path.lineTo(endX, endY);
+ return path;
+ }
+
private boolean isSelected() {
return NodeUtil.isSelected(this, 1);
}
}
private Rectangle2D calculateBounds(Rectangle2D rect) {
- return edge.getBounds(rect);
+ return calculatePath(edge).getBounds2D();
}
public void setDNEdge(DistrictNetworkEdge edge) {
private Color color;
+ private Rectangle2D bounds;
+
@Override
public void init() {
setZIndex(2);
}
scaleRecip = 8.0 * scaleRecip;
+ // Translate lat and lon to X and Y
+ Point2D res = calculatePoint2D(vertex);
+
Rectangle2D toDraw;
if (hover) {
- toDraw = new Rectangle2D.Double(HOVERED.getX() * scaleRecip, HOVERED.getY() * scaleRecip, HOVERED.getWidth() * scaleRecip, HOVERED.getHeight() * scaleRecip);
+ toDraw = new Rectangle2D.Double(res.getX() - (HOVERED.getWidth() / 2 * scaleRecip), res.getY() - (HOVERED.getHeight() / 2 * scaleRecip), HOVERED.getWidth() * scaleRecip, HOVERED.getHeight() * scaleRecip);
} else {
- toDraw = new Rectangle2D.Double(NORMAL.getX() * scaleRecip, NORMAL.getY() * scaleRecip, NORMAL.getWidth() * scaleRecip, NORMAL.getHeight() * scaleRecip);
+ toDraw = new Rectangle2D.Double(res.getX() - (NORMAL.getWidth() / 2 * scaleRecip), res.getY() - (NORMAL.getHeight() / 2 * scaleRecip), NORMAL.getWidth() * scaleRecip, NORMAL.getHeight() * scaleRecip);
}
// render
g2d.fill(toDraw);
g2d.setTransform(ot);
}
+ @Override
+ public Rectangle2D getBounds() {
+ return super.getBounds();
+ }
+
@Override
public Rectangle2D getBoundsInLocal() {
- if (hover)
- return HOVERED;
- return NORMAL;
+ return bounds;
+ }
+
+ private void updateBounds() {
+ Rectangle2D oldBounds = bounds;
+ if (oldBounds == null)
+ oldBounds = new Rectangle2D.Double();
+ bounds = calculateBounds(oldBounds);
+ }
+
+ @Override
+ public void setTransform(AffineTransform transform) {
+ super.setTransform(transform);
+ // Update bounds
+ updateBounds();
+ }
+
+ private Rectangle2D calculateBounds(Rectangle2D rect) {
+ Point2D calcPoint = calculatePoint2D(vertex);
+ AffineTransform at = getTransform();
+ return new Rectangle2D.Double(calcPoint.getX(), calcPoint.getY(), 1 / at.getScaleX(), 1 / at.getScaleY()).getBounds2D();
+ }
+
+ private static Point2D calculatePoint2D(DistrictNetworkVertex vertex) {
+ Point2D point= vertex.getPoint();
+ double x = ModelledCRS.longitudeToX(point.getX());
+ double y = ModelledCRS.latitudeToY(point.getY());
+
+ // Apply the scaling
+ Point2D res = new Point2D.Double(x, y);
+ return res;
}
public void setVertex(DistrictNetworkVertex vertex) {
this.vertex = vertex;
+ updateBounds();
}
public boolean hover(boolean hover) {
@Override
protected double modifyHorizontalValue(double value) {
- // TODO: fix scale!
- double scale = 100000;
-// double scale = 1;
- return ModelledCRS.xToLongitude(value / scale);
+ return ModelledCRS.xToLongitude(value);
}
@Override
protected double modifyVerticalValue(double value) {
- // TODO: fix scale!
- double scale = 100000;
-// double scale = 1;
- return ModelledCRS.yToLatitude(value / scale);
+ return ModelledCRS.yToLatitude(value);
}
}
* String str = formatValue(val);
*/
// TODO: fix scale
- double scale = 100000;
-// double scale = 1;
- double startLat = ModelledCRS.yToLatitude(start.getY() / scale);
- double startLon = ModelledCRS.xToLongitude(start.getX() / scale);
+ double scaleY = getTransform().getScaleY();
+ double scaleX = getTransform().getScaleX();
- double endLat = ModelledCRS.yToLatitude(end.getY() / scale);
- double endLon = ModelledCRS.xToLongitude(end.getX() / scale);
+ double startLat = ModelledCRS.yToLatitude(start.getY() / scaleY);
+ double startLon = ModelledCRS.xToLongitude(start.getX() / scaleX);
+
+ double endLat = ModelledCRS.yToLatitude(end.getY() / scaleY);
+ double endLon = ModelledCRS.xToLongitude(end.getX() / scaleX);
double[] startCoords = new double[] { startLon, startLat };
double[] endCoords = new double[] { endLon, endLat };
@Override
public void perform(WriteGraph graph) throws DatabaseException {
- builder.create(graph, startCoords, endCoords, padding / scale);
+ builder.create(graph, startCoords, endCoords, 1 / padding);
}
});
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Collection;
import org.simantics.diagram.stubs.DiagramResource;
import org.simantics.district.network.ModelledCRS;
import org.simantics.district.network.ontology.DistrictNetworkResource;
+import org.simantics.district.network.ui.adapters.DistrictNetworkVertexElement;
+import org.simantics.district.network.ui.nodes.DistrictNetworkVertexNode;
import org.simantics.g2d.canvas.Hints;
import org.simantics.g2d.diagram.participant.pointertool.TranslateMode;
import org.simantics.g2d.element.ElementUtils;
DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
DiagramResource DIA = DiagramResource.getInstance(graph);
for (IElement e : elementsToReallyTranslate) {
+
+ DistrictNetworkVertexNode node = e.getHint(DistrictNetworkVertexElement.KEY_DN_VERTEX_NODE);
+ Rectangle2D bounds = node.getBounds();
+
Object obj = ElementUtils.getObject(e);
if (obj instanceof Resource) {
Resource res = (Resource) obj;
double x = at.getTranslateX();
double y = at.getTranslateY();
- // TODO: Fix scale!
- double scale = 100000;
-// double scale = 1;
- double lat = ModelledCRS.yToLatitude(y / scale);
- double lon = ModelledCRS.xToLongitude(x / scale);
+
+ double lat = ModelledCRS.yToLatitude(y / at.getScaleY());
+ double lon = ModelledCRS.xToLongitude(x / at.getScaleX());
// write to db
double[] coords = new double[] { lon, lat };
package org.simantics.district.network.ui.participants;
import org.simantics.district.network.ui.nodes.MapRulerNode;
+import org.simantics.g2d.canvas.impl.SGNodeReflection.SGInit;
import org.simantics.g2d.participant.RulerPainter;
+import org.simantics.maps.MapScalingTransform;
+import org.simantics.scenegraph.g2d.G2DParentNode;
public class MapRulerPainter extends RulerPainter {
+ @SGInit
+ @Override
+ public void initSG(G2DParentNode parent) {
+ node = parent.addNode("ruler", getNodeClass());
+ node.setTransform(MapScalingTransform.INSTANCE);
+ node.setZIndex(PAINT_PRIORITY);
+ updateNode();
+ }
+
@Override
protected Class<MapRulerNode> getNodeClass() {
return MapRulerNode.class;
import java.io.IOException;
import java.net.URISyntaxException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
import java.util.List;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jface.preference.FileFieldEditor;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.IntegerFieldEditor;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.simantics.district.maps.server.TileserverMapnik;
import org.simantics.district.maps.server.TileserverMapnikInstance;
import org.simantics.district.maps.server.prefs.MapsServerPreferences;
-import org.simantics.ui.workbench.e4.E4WorkbenchUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private TileserverMapnik server;
+ private FileFieldEditor addNew;
+
public MapsServerPreferencePage() {
super(GRID);
setDescription("Maps server preferences");
namesAndValues[i] = nameAndValue;
}
- ComboFieldEditor selector = new ComboFieldEditor("Styles", "Tile Styles", namesAndValues, parent);
+ ComboFieldEditor selector = new ComboFieldEditor(MapsServerPreferences.P_CURRENT_TM2STYLE, "Tile Styles", namesAndValues, parent);
+ addField(selector);
} catch (IOException e) {
e.printStackTrace();
}
createTilesField(tilesGroup);
- GridLayoutFactory.fillDefaults().numColumns(2).equalWidth(false).extendedMargins(12, 12, 12, 12).spacing(5, 4).applyTo(tilesGroup);
+ GridLayoutFactory.fillDefaults().numColumns(3).equalWidth(false).extendedMargins(12, 12, 12, 12).spacing(5, 4).applyTo(tilesGroup);
}
private void createTilesField(Composite parent) {
namesAndValues[i] = nameAndValue;
}
- ComboFieldEditor selector = new ComboFieldEditor("MBTiles", "MBTiles", namesAndValues, parent);
-
+ ComboFieldEditor selector = new ComboFieldEditor(MapsServerPreferences.P_CURRENT_MBTILES, "MBTiles", namesAndValues, parent);
+ addField(selector);
- FileFieldEditor addNew = new FileFieldEditor("add new", "Add new tiles", parent);
+ addNew = new FileFieldEditor("Add new tiles", "Add new tiles", parent);
+ addNew.setPropertyChangeListener(new IPropertyChangeListener() {
+
+ @Override
+ public void propertyChange(PropertyChangeEvent event) {
+ System.out.println(event);
+ }
+ });
} catch (IOException e) {
LOGGER.error("Could not create tiles field", e);
}
}
+ @Override
+ protected void performApply() {
+ // Upload new mbtiles file
+ String fileLocation = addNew.getStringValue();
+ if (fileLocation != null && !fileLocation.isEmpty()) {
+ Path p = Paths.get(fileLocation);
+ Path target = server.getDataDirectory().resolve(p.getFileName());
+ try {
+ Files.copy(p, target);
+ } catch (IOException e) {
+ String message = "Could not upload " + fileLocation + " to " + target.toAbsolutePath();
+ LOGGER.error(message, e);
+ setErrorMessage(message);
+ }
+ }
+ super.performApply();
+ }
+
+ @Override
+ public boolean performOk() {
+ boolean success = super.performOk();
+
+ try {
+ server.restart();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ return success;
+ }
}
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Server
-Bundle-SymbolicName: org.simantics.maps.server
+Bundle-SymbolicName: org.simantics.maps.server;singleton:=true
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: org.simantics.district.maps.server.Activator
Require-Bundle: org.eclipse.core.runtime,
lib/logback-core-1.2.1.jar,\
lib/snakeyaml-1.18.jar,\
lib/jna-4.3.0.jar,\
- lib/zt-process-killer-1.6.jar
+ lib/zt-process-killer-1.6.jar,\
+ plugin.xml
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension
+ point="org.eclipse.core.runtime.preferences">
+ <initializer
+ class="org.simantics.district.maps.server.prefs.MapsServerInitializer">
+ </initializer>
+ </extension>
+
+</plugin>
public static final String PLUGIN_ID = "org.simantics.maps.server";
private static BundleContext context;
+ private static Activator defaultt;
static BundleContext getContext() {
return context;
*/
public void start(BundleContext bundleContext) throws Exception {
Activator.context = bundleContext;
+ Activator.defaultt = this;
}
/*
*/
public void stop(BundleContext bundleContext) throws Exception {
Activator.context = null;
+ Activator.defaultt = null;
}
public static Path getNodeJSRoot() throws IOException, URISyntaxException {
return Paths.get(encodedUri);
}
+ public static Activator getDefault() {
+ return defaultt;
+ }
+
}
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Stream;
+import org.simantics.district.maps.server.prefs.MapsServerPreferences;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yaml.snakeyaml.Yaml;
private SystemProcess process;
private Path serverRoot;
- private int port;
private AtomicBoolean running = new AtomicBoolean(false);
- TileserverMapnik(Path serverRoot, int port) {
+ TileserverMapnik(Path serverRoot) {
this.serverRoot = serverRoot.normalize();
- this.port = port;
- }
-
- public void setPort(int port) {
- this.port = port;
}
public boolean isRunning() throws IOException, InterruptedException {
return;
StartedProcess startedProcess = new ProcessExecutor().directory(serverRoot.resolve("tileserver-mapnik").toFile()).destroyOnExit().environment(getEnv())
- .command(NodeJS.executable().toString(), getTessera().toString(), "-c", getConfigJson().toString())
+ .command(NodeJS.executable().toString(), getTessera().toString(), "-c", getConfigJson().toString(), "-p", Integer.toString(MapsServerPreferences.defaultPort()))
.redirectOutput(Slf4jStream.ofCaller().asDebug()).start();
Process nativeProcess = startedProcess.getProcess();
}
public List<String> availableMBTiles() throws IOException {
- Path data = serverRoot.resolve("data").toAbsolutePath();
+ Path data = getDataDirectory();
List<String> result = new ArrayList<>();
try (Stream<Path> paths = Files.walk(data)) {
paths.forEach(p -> {
private void checkConfigJson() throws JsonParseException, JsonMappingException, IOException {
Path configJson = getConfigJson();
Map<String, Object> config = new HashMap<>();
- Path tm2 = serverRoot.resolve("tm2").toAbsolutePath();
+ Path tm2 = getStyleDirectory();
try (DirectoryStream<Path> stream = Files.newDirectoryStream(tm2)) {
stream.forEach(p -> {
Path projectYaml = p.resolve("project.yml");
mapper.writerWithDefaultPrettyPrinter().writeValue(Files.newOutputStream(configJson, StandardOpenOption.TRUNCATE_EXISTING), config);
}
+ public Path getStyleDirectory() {
+ return serverRoot.resolve("tm2");
+ }
+
+ public Path getDataDirectory() {
+ return serverRoot.resolve("data");
+ }
+
+ public Path getCurrentTiles() {
+ return getDataDirectory().resolve(MapsServerPreferences.currentMBTiles());
+ }
+
public void checkTm2Styles() {
- Path tm2 = serverRoot.resolve("tm2").toAbsolutePath();
+ Path tm2 = getStyleDirectory();
try (DirectoryStream<Path> stream = Files.newDirectoryStream(tm2)) {
stream.forEach(p -> {
Path projectYaml = p.resolve("project.yml");
try (InputStream input = Files.newInputStream(projectYaml, StandardOpenOption.READ)) {
data = yaml.loadAs(input, Map.class);
- Path tiles = serverRoot.relativize(serverRoot.resolve("data").resolve("helsinki_finland.mbtiles"));//.toAbsolutePath().toString().replace("\\", "/");
-
+ Path tiles = serverRoot.relativize(getCurrentTiles());
String tmStyle = "mbtiles://../" + tiles.toString();
data.put("source", tmStyle);
public List<String> listStyles() throws IOException {
List<String> results = new ArrayList<>();
- Path tm2 = serverRoot.resolve("tm2").toAbsolutePath();
+ Path tm2 = getStyleDirectory();
try (DirectoryStream<Path> stream = Files.newDirectoryStream(tm2)) {
stream.forEach(p -> {
results.add(p.getFileName().toString());
import java.io.IOException;
import java.net.URISyntaxException;
-import org.simantics.district.maps.server.prefs.MapsServerPreferences;
-
public class TileserverMapnikInstance {
private static TileserverMapnik INSTANCE;
public static synchronized TileserverMapnik get() throws IOException, URISyntaxException {
if (INSTANCE == null)
- INSTANCE = new TileserverMapnik(Activator.getTileserverMapnikRoot(), MapsServerPreferences.defaultPort());
+ INSTANCE = new TileserverMapnik(Activator.getTileserverMapnikRoot());
return INSTANCE;
}
}
package org.simantics.district.maps.server.prefs;
+import java.util.Arrays;
+import java.util.List;
+
import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;
public class MapsServerInitializer extends AbstractPreferenceInitializer {
public void initializeDefaultPreferences() {
Preferences node = MapsServerPreferences.getPreferences();
- node.putBoolean(MapsServerPreferences.P_START_AUTOMATICALLY, true);
- node.putInt(MapsServerPreferences.P_DEFAULT_PORT, 8080);
+ try {
+ String[] keys = node.keys();
+ List<String> keyss = Arrays.asList(keys);
+ if (!keyss.contains(MapsServerPreferences.P_START_AUTOMATICALLY)) {
+ node.putBoolean(MapsServerPreferences.P_START_AUTOMATICALLY, true);
+ }
+ if (!keyss.contains(MapsServerPreferences.P_DEFAULT_PORT)) {
+ node.putInt(MapsServerPreferences.P_DEFAULT_PORT, 8080);
+ }
+ } catch (BackingStoreException e) {
+ e.printStackTrace();
+ }
}
-
}
package org.simantics.district.maps.server.prefs;
-import org.eclipse.core.runtime.preferences.DefaultScope;
+import org.eclipse.core.runtime.preferences.InstanceScope;
import org.osgi.service.prefs.Preferences;
-//import org.simantics.maps.server.ui.Activator;
import org.simantics.district.maps.server.Activator;
public class MapsServerPreferences {
public static final String P_START_AUTOMATICALLY = "org.simantics.maps.server.startAutomatically";
public static final String P_DEFAULT_PORT = "org.simantics.maps.server.defaultPort";
+
+ public static final String P_CURRENT_MBTILES = "org.simantics.maps.server.currentMbTiles";
+
+ public static final String P_CURRENT_TM2STYLE = "org.simantics.maps.server.currentTM2Style";
public static Preferences getPreferences() {
- return DefaultScope.INSTANCE.getNode(MapsServerPreferences.P_NODE);
+ return InstanceScope.INSTANCE.getNode(MapsServerPreferences.P_NODE);
}
public static boolean startAutomatically() {
public static int defaultPort() {
return getPreferences().getInt(P_DEFAULT_PORT, 8080);
}
+
+ public static String currentMBTiles() {
+ return getPreferences().get(P_CURRENT_MBTILES, "");
+ }
+
+ public static String currentTM2Style() {
+ return getPreferences().get(P_CURRENT_TM2STYLE, "");
+ }
}