Permalink
Browse files

Polyline, Polygon overlays touch events #998 #999 (#1000)

  • Loading branch information...
devemux86 committed Oct 5, 2017
1 parent dbee700 commit 973a929fe7e303e2ccad475efc60170af00221bb
View
@@ -4,6 +4,8 @@
- Map frame buffer improvements [#977](https://github.com/mapsforge/mapsforge/issues/977)
- Hillshading improvements [#997](https://github.com/mapsforge/mapsforge/issues/997)
- Polyline overlay touch events [#998](https://github.com/mapsforge/mapsforge/issues/998)
- Polygon overlay touch events [#999](https://github.com/mapsforge/mapsforge/issues/999)
- Circle overlay touch events [#996](https://github.com/mapsforge/mapsforge/issues/996)
- MapFile supports FileChannel as input [#982](https://github.com/mapsforge/mapsforge/issues/982)
- XmlPullParser different implementations [#974](https://github.com/mapsforge/mapsforge/issues/974)
@@ -1,7 +1,7 @@
/*
* Copyright 2010, 2011, 2012, 2013 mapsforge.org
* Copyright 2014 Ludwig M Brinckmann
* Copyright 2016 devemux86
* Copyright 2016-2017 devemux86
*
* 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
@@ -21,6 +21,8 @@
public interface Paint {
int getColor();
float getStrokeWidth();
int getTextHeight(String text);
int getTextWidth(String text);
@@ -2,7 +2,7 @@
* Copyright 2010, 2011, 2012, 2013 mapsforge.org
* Copyright 2014 Ludwig M Brinckmann
* Copyright 2014 Christian Pesch
* Copyright 2014-2016 devemux86
* Copyright 2014-2017 devemux86
* Copyright 2015 Andreas Schildbach
*
* This program is free software: you can redistribute it and/or modify it under the
@@ -21,6 +21,7 @@
import org.mapsforge.core.model.BoundingBox;
import org.mapsforge.core.model.Dimension;
import org.mapsforge.core.model.LatLong;
import org.mapsforge.core.model.Point;
import java.util.ArrayList;
import java.util.List;
@@ -74,8 +75,9 @@
private static final String DELIMITER = ",";
/**
* Find if the given point lies within this polygon.<br/>
* See http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
* Find if the given point lies within this polygon.
* <p>
* http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
*
* @return true if this polygon contains the given point, false otherwise.
*/
@@ -91,6 +93,25 @@ public static boolean contains(LatLong[] latLongs, LatLong latLong) {
return result;
}
/**
* Find if the given point lies within this polygon.
* <p>
* http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
*
* @return true if this polygon contains the given point, false otherwise.
*/
public static boolean contains(List<LatLong> latLongs, LatLong latLong) {
boolean result = false;
for (int i = 0, j = latLongs.size() - 1; i < latLongs.size(); j = i++) {
if ((latLongs.get(i).latitude > latLong.latitude) != (latLongs.get(j).latitude > latLong.latitude)
&& (latLong.longitude < (latLongs.get(j).longitude - latLongs.get(i).longitude) * (latLong.latitude - latLongs.get(i).latitude)
/ (latLongs.get(j).latitude - latLongs.get(i).latitude) + latLongs.get(i).longitude)) {
result = !result;
}
}
return result;
}
/**
* Converts a coordinate from degrees to microdegrees (degrees * 10^6). No validation is performed.
*
@@ -138,6 +159,16 @@ public static double distance(LatLong latLong1, LatLong latLong2) {
return Math.hypot(latLong1.longitude - latLong2.longitude, latLong1.latitude - latLong2.latitude);
}
/**
* Returns the distance between the given segment and point.
* <p>
* libGDX (Apache 2.0)
*/
public static double distanceSegmentPoint(double startX, double startY, double endX, double endY, double pointX, double pointY) {
Point nearest = nearestSegmentPoint(startX, startY, endX, endY, pointX, pointY);
return Math.hypot(nearest.x - pointX, nearest.y - pointY);
}
/**
* Creates a new LatLong from a comma-separated string of coordinates in the order latitude, longitude. All
* coordinate values must be in degrees.
@@ -191,6 +222,22 @@ public static double microdegreesToDegrees(int coordinate) {
return coordinate / CONVERSION_FACTOR;
}
/**
* Returns a point on the segment nearest to the specified point.
* <p>
* libGDX (Apache 2.0)
*/
public static Point nearestSegmentPoint(double startX, double startY, double endX, double endY, double pointX, double pointY) {
double xDiff = endX - startX;
double yDiff = endY - startY;
double length2 = xDiff * xDiff + yDiff * yDiff;
if (length2 == 0) return new Point(startX, startY);
double t = ((pointX - startX) * (endX - startX) + (pointY - startY) * (endY - startY)) / length2;
if (t < 0) return new Point(startX, startY);
if (t > 1) return new Point(endX, endY);
return new Point(startX + t * (endX - startX), startY + t * (endY - startY));
}
/**
* Parses a given number of comma-separated coordinate values from the supplied string.
*
@@ -1,7 +1,7 @@
/*
* Copyright 2010, 2011, 2012, 2013 mapsforge.org
* Copyright 2014 Ludwig M Brinckmann
* Copyright 2015-2016 devemux86
* Copyright 2015-2017 devemux86
*
* 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
@@ -144,6 +144,11 @@ public int getColor() {
return this.paint.getColor();
}
@Override
public float getStrokeWidth() {
return paint.getStrokeWidth();
}
@Override
public int getTextHeight(String text) {
this.paint.getTextBounds(text, 0, text.length(), rect);
@@ -150,6 +150,11 @@ public int getColor() {
return this.color.getRGB();
}
@Override
public float getStrokeWidth() {
return this.strokeWidth;
}
@Override
public int getTextHeight(String text) {
Graphics2D graphics2d = bufferedImage.createGraphics();
@@ -1,7 +1,7 @@
/*
* Copyright 2010, 2011, 2012, 2013 mapsforge.org
* Copyright 2014 Ludwig M Brinckmann
* Copyright 2015 devemux86
* Copyright 2015-2017 devemux86
*
* 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
@@ -23,6 +23,7 @@
import org.mapsforge.core.model.BoundingBox;
import org.mapsforge.core.model.LatLong;
import org.mapsforge.core.model.Point;
import org.mapsforge.core.util.LatLongUtils;
import org.mapsforge.core.util.MercatorProjection;
import org.mapsforge.map.layer.Layer;
@@ -69,6 +70,10 @@ public Polygon(Paint paintFill, Paint paintStroke, GraphicFactory graphicFactory
this.graphicFactory = graphicFactory;
}
public synchronized boolean contains(LatLong tapLatLong) {
return LatLongUtils.contains(latLongs, tapLatLong);
}
@Override
public synchronized void draw(BoundingBox boundingBox, byte zoomLevel, Canvas canvas, Point topLeftPoint) {
if (this.latLongs.size() < 2 || (this.paintStroke == null && this.paintFill == null)) {
@@ -1,7 +1,7 @@
/*
* Copyright 2010, 2011, 2012, 2013 mapsforge.org
* Copyright 2014 Ludwig M Brinckmann
* Copyright 2015 devemux86
* Copyright 2015-2017 devemux86
*
* 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
@@ -23,8 +23,10 @@
import org.mapsforge.core.model.BoundingBox;
import org.mapsforge.core.model.LatLong;
import org.mapsforge.core.model.Point;
import org.mapsforge.core.util.LatLongUtils;
import org.mapsforge.core.util.MercatorProjection;
import org.mapsforge.map.layer.Layer;
import org.mapsforge.map.util.MapViewProjection;
import java.util.Iterator;
import java.util.List;
@@ -65,6 +67,21 @@ public Polyline(Paint paintStroke, GraphicFactory graphicFactory, boolean keepAl
this.graphicFactory = graphicFactory;
}
public synchronized boolean contains(Point tapXY, MapViewProjection mapViewProjection) {
// Touch min 20 px at baseline mdpi (160dpi)
double distance = Math.max(20 / 2 * this.displayModel.getScaleFactor(),
this.paintStroke.getStrokeWidth() / 2);
Point point2 = null;
for (int i = 0; i < this.latLongs.size() - 1; i++) {
Point point1 = i == 0 ? mapViewProjection.toPixels(this.latLongs.get(i)) : point2;
point2 = mapViewProjection.toPixels(this.latLongs.get(i + 1));
if (LatLongUtils.distanceSegmentPoint(point1.x, point1.y, point2.x, point2.y, tapXY.x, tapXY.y) <= distance) {
return true;
}
}
return false;
}
@Override
public synchronized void draw(BoundingBox boundingBox, byte zoomLevel, Canvas canvas, Point topLeftPoint) {
if (this.latLongs.isEmpty() || this.paintStroke == null) {
@@ -62,7 +62,8 @@
protected void addOverlayLayers(Layers layers) {
Polyline polyline = new Polyline(Utils.createPaint(
AndroidGraphicFactory.INSTANCE.createColor(Color.BLUE), 8,
AndroidGraphicFactory.INSTANCE.createColor(Color.BLUE),
(int) (8 * mapView.getModel().displayModel.getScaleFactor()),
Style.STROKE), AndroidGraphicFactory.INSTANCE);
List<LatLong> latLongs = polyline.getLatLongs();
latLongs.add(latLong1);
@@ -75,7 +76,16 @@ protected void addOverlayLayers(Layers layers) {
Paint shaderPaint = Utils.createPaint(AndroidGraphicFactory.INSTANCE.createColor(Color.GREEN), 90, Style.STROKE);
shaderPaint.setBitmapShader(AndroidGraphicFactory.convertToBitmap(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? getDrawable(R.drawable.marker_green) : getResources().getDrawable(R.drawable.marker_green)));
Polyline polylineWithShader = new Polyline(shaderPaint, AndroidGraphicFactory.INSTANCE, true);
Polyline polylineWithShader = new Polyline(shaderPaint, AndroidGraphicFactory.INSTANCE, true) {
@Override
public boolean onTap(LatLong tapLatLong, Point layerXY, Point tapXY) {
if (contains(tapXY, mapView.getMapViewProjection())) {
Toast.makeText(OverlayMapViewer.this, "Polyline tap\n" + tapLatLong, Toast.LENGTH_SHORT).show();
return true;
}
return false;
}
};
List<LatLong> latLongs2 = polylineWithShader.getLatLongs();
latLongs2.add(latLong7);
latLongs2.add(latLong8);
@@ -87,8 +97,16 @@ protected void addOverlayLayers(Layers layers) {
Paint paintStroke = Utils.createPaint(
AndroidGraphicFactory.INSTANCE.createColor(Color.BLACK), 2,
Style.STROKE);
Polygon polygon = new Polygon(paintFill, paintStroke,
AndroidGraphicFactory.INSTANCE);
Polygon polygon = new Polygon(paintFill, paintStroke, AndroidGraphicFactory.INSTANCE) {
@Override
public boolean onTap(LatLong tapLatLong, Point layerXY, Point tapXY) {
if (contains(tapLatLong)) {
Toast.makeText(OverlayMapViewer.this, "Polygon tap\n" + tapLatLong, Toast.LENGTH_SHORT).show();
return true;
}
return false;
}
};
List<LatLong> latLongs3 = polygon.getLatLongs();
latLongs3.add(latLong2);
latLongs3.add(latLong3);

0 comments on commit 973a929

Please sign in to comment.