DN.HideStyle : DIA.Style
DN.VertexSymbolStyle : DIA.Style
DN.ConnectionLineStyle : DIA.Style
+DN.ElevationRectangleStyle : DIA.Style
// Style for user component-specified text grid entries
DN.DistrictNetworkHoverInfoStyle : DIA.Style
class="org.simantics.district.network.ui.nodes.DistrictNetworkStaticInfoStyle">
<this />
</resource>
+ <resource uri="http://www.simantics.org/DistrictNetwork-1.0/ElevationRectangleStyle"
+ class="org.simantics.district.network.ui.nodes.ElevationRectangleStyle">
+ </resource>
</target>
<target interface="org.simantics.g2d.diagram.DiagramClass">
name="District Network Breakdown"
restorable="true">
</e4view>
+ <e4view
+ class="org.simantics.district.network.ui.table.DistrictCSVTableView"
+ icon="platform:/plugin/com.famfamfam.silk/icons/table_edit.png"
+ id="org.simantics.district.network.ui.table.csvTableView"
+ name="District CSV Import Table"
+ restorable="true"
+ allowMultiple="false">
+ </e4view>
</extension>
<extension
point="org.eclipse.ui.preferencePages">
import org.simantics.diagram.ui.DiagramModelHints;
import org.simantics.district.network.DistrictNetworkUtil;
import org.simantics.district.network.ui.participants.DNPointerInteractor;
+import org.simantics.district.network.ui.participants.ElevationServerParticipant;
import org.simantics.district.network.ui.participants.MapRulerPainter;
import org.simantics.g2d.canvas.ICanvasContext;
import org.simantics.g2d.canvas.impl.CanvasContext;
ctx.add(new MapPainter(tr));
ctx.add(new NetworkDrawingParticipant(tr));
+ ctx.add(new ElevationServerParticipant(tr));
}
protected String getPopupId() {
--- /dev/null
+package org.simantics.district.network.ui.nodes;
+
+import java.awt.geom.Rectangle2D;
+import java.util.Collection;
+import java.util.Collections;
+
+import org.simantics.db.RequestProcessor;
+import org.simantics.db.Resource;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.maps.elevation.server.SingletonTiffTileInterface;
+import org.simantics.scenegraph.g2d.IG2DNode;
+import org.simantics.scenegraph.profile.EvaluationContext;
+import org.simantics.scenegraph.profile.Group;
+import org.simantics.scenegraph.profile.Style;
+import org.simantics.scenegraph.profile.common.ObserverGroupListener;
+import org.simantics.scenegraph.utils.NodeUtil;
+
+public class ElevationRectangleStyle implements Style {
+
+ private ObserverGroupListener listener = null;
+ private double priority;
+
+ @Override
+ public void activate(RequestProcessor backend, Resource runtimeDiagram, Resource entry, Group group, EvaluationContext observer) throws DatabaseException {
+ if (listener != null && !listener.isDisposed())
+ return;
+ listener = new ObserverGroupListener(this, group, observer);
+ group.trackItems(backend, runtimeDiagram, listener);
+ }
+
+ @Override
+ public void deactivate(Resource runtimeDiagram, Resource entry, Group group, EvaluationContext observer) {
+ if (listener != null && !listener.isDisposed()) {
+ setRectangles(observer, Collections.emptyList());
+ listener.dispose();
+ observer.update();
+ }
+ }
+
+ @Override
+ public void apply(Resource entry, Group group, EvaluationContext observer) {
+ apply2(entry, observer);
+ }
+
+ @Override
+ public void apply2(Object item, EvaluationContext observer) {
+ setRectangles(observer, SingletonTiffTileInterface.getBoundingBoxes());
+ }
+
+ private void setRectangles(EvaluationContext observer, Collection<Rectangle2D> rectangles) {
+ IG2DNode node = NodeUtil.getNearestChildByClass(observer.getSceneGraph(), ElevationServerNode.class);
+ if (node != null) {
+ ((ElevationServerNode) node).setRectangles(rectangles);
+ }
+ }
+
+ @Override
+ public void setPriority(double priority) {
+ this.priority = priority;
+ }
+
+ @Override
+ public double getPriority() {
+ return priority;
+ }
+
+}
--- /dev/null
+package org.simantics.district.network.ui.nodes;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.Stroke;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.Collection;
+import java.util.Collections;
+
+import org.simantics.scenegraph.g2d.G2DNode;
+import org.simantics.scenegraph.utils.GeometryUtils;
+
+public class ElevationServerNode extends G2DNode {
+
+ private static final long serialVersionUID = 3832908017166017921L;
+
+ private static final Stroke DASHED_STROKE = new BasicStroke(2.0f,
+ BasicStroke.CAP_ROUND,
+ BasicStroke.JOIN_ROUND,
+ 4.0f, new float[]{4.0f}, 0.0f);
+
+ private static final Color BLUE_ALPHA = new Color(0, 0, 255, 100);
+
+ public static final String ID = "elevationServerNode";
+
+ private Collection<Rectangle2D> rectangles;
+
+ @Override
+ public void render(Graphics2D g2d) {
+
+ Color old = g2d.getColor();
+ Stroke oldStroke = g2d.getStroke();
+
+ g2d.setColor(BLUE_ALPHA);
+ BasicStroke stroke = GeometryUtils.scaleStroke(DASHED_STROKE, (float) (1.0 / GeometryUtils.getScale(g2d.getTransform())));
+ g2d.setStroke(stroke);
+
+ double scale = getTransform().getScaleY();
+
+ for (Rectangle2D rect : getRectangles()) {
+
+ Point2D point = new Point2D.Double(rect.getY(), rect.getX());
+ Point2D result = DistrictNetworkNodeUtils.calculatePoint2D(point, null);
+
+ Point2D point2 = new Point2D.Double(rect.getY() + rect.getHeight(), rect.getX() + rect.getWidth());
+ Point2D result2 = DistrictNetworkNodeUtils.calculatePoint2D(point2, null);
+
+ double x = result.getX() * scale;
+ double y = result.getY() * scale;
+ double width = result2.getX() * scale - result.getX() * scale;
+ double height = result2.getY() * scale - result.getY() * scale;
+
+ Rectangle2D translated = new Rectangle2D.Double(x, y, width, Math.abs(height));
+ g2d.draw(translated);
+ }
+
+ g2d.setStroke(oldStroke);
+ g2d.setColor(old);
+ }
+
+ @Override
+ public Rectangle2D getBoundsInLocal() {
+ Rectangle2D bounds = new Rectangle2D.Double();
+ for (Rectangle2D rect : getRectangles()) {
+ bounds.add(rect);
+ }
+ return bounds;
+ }
+
+ public void setRectangles(Collection<Rectangle2D> rectangles) {
+ this.rectangles = rectangles;
+ }
+
+ public Collection<Rectangle2D> getRectangles() {
+ if (rectangles == null)
+ return Collections.emptyList();
+ return rectangles;
+ }
+}
--- /dev/null
+package org.simantics.district.network.ui.participants;
+
+import java.awt.geom.AffineTransform;
+
+import org.simantics.district.network.ui.nodes.ElevationServerNode;
+import org.simantics.g2d.canvas.impl.SGNodeReflection.SGInit;
+import org.simantics.g2d.diagram.participant.AbstractDiagramParticipant;
+import org.simantics.scenegraph.g2d.G2DParentNode;
+
+public class ElevationServerParticipant extends AbstractDiagramParticipant {
+
+ private ElevationServerNode node;
+
+ private AffineTransform transform;
+
+ public ElevationServerParticipant(AffineTransform transform) {
+ this.transform = transform;
+ }
+
+ @SGInit
+ public void initSG(G2DParentNode parent) {
+ node = parent.addNode(ElevationServerNode.ID, ElevationServerNode.class);
+ node.setTransform(transform);
+ }
+
+}
org.simantics.diagram,
org.simantics.scenegraph.profile;bundle-version="1.0.0",
org.simantics;bundle-version="1.0.0",
- org.slf4j.api
+ org.slf4j.api,
+ org.simantics.maps.elevation.server;bundle-version="1.0.0"
Export-Package: org.simantics.district.network,
org.simantics.district.network.changeset,
org.simantics.district.network.profile
addField(automatically);
IntegerFieldEditor pipeDepth = new IntegerFieldEditor(MapsElevationServerPreferences.P_PIPE_DEPTH_UNDER_GROUND, "Pipe depth under ground", serverGroup);
+ pipeDepth.setValidRange(Integer.MIN_VALUE, Integer.MAX_VALUE);
addField(pipeDepth);
GridLayoutFactory.fillDefaults().numColumns(2).equalWidth(false).extendedMargins(12, 12, 12, 12).spacing(5, 4).applyTo(serverGroup);
package org.simantics.maps.elevation.server;
+import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.util.Collection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public static Number lookup(double x, double y) {
return instance.tileInterface.lookup(x, y);
}
+
+ public static Collection<Rectangle2D> getBoundingBoxes() {
+ return instance.tileInterface.getBoundingBoxes();
+ }
}
package org.simantics.maps.elevation.server;
+import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.util.Collection;
import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
import java.util.stream.Stream;
-import com.github.benmanes.caffeine.cache.Caffeine;
-import com.github.benmanes.caffeine.cache.LoadingCache;
-import com.vividsolutions.jts.geom.Coordinate;
-import com.vividsolutions.jts.geom.Envelope;
-import com.vividsolutions.jts.index.strtree.STRtree;
-
import org.geotools.geometry.DirectPosition2D;
import org.geotools.geometry.Envelope2D;
import org.geotools.referencing.CRS;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.github.benmanes.caffeine.cache.Caffeine;
+import com.github.benmanes.caffeine.cache.LoadingCache;
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Envelope;
+import com.vividsolutions.jts.index.strtree.STRtree;
+
public class TiffTileInterface {
private static final Logger LOGGER = LoggerFactory.getLogger(TiffTileInterface.class);
synchronized(index) {
index.insert(envelope, tifFile);
}
+ envelopes.put(tifFile, envelope);
} catch (Exception e) {
LOGGER.error("Could not initialize index for file {}", tifFile, e);
} finally {
});
}
+ private Map<Path, Envelope> envelopes = new ConcurrentHashMap<>();
+
+ public Collection<Rectangle2D> getBoundingBoxes() {
+ Collection<Rectangle2D> rects = envelopes.values().stream().map(env -> {
+ double x = env.getMinX();
+ double y = env.getMinY();
+ return new Rectangle2D.Double(x, y, env.getMaxX() - x, env.getMaxY() - y);
+ }).collect(Collectors.toList());
+ return rects;
+ }
+
private static CoordinateReferenceSystem c4326;
static {