我正在使用GMapsFx构建JavaFx应用程序并尝试在其中嵌入Google地图。
我尝试使用此API在地图顶部绘制省略号,但API仅提供弧线。
因此,为了解决这个问题,我尝试绘制四分之三的椭圆,但设法只绘制了四分之三的圆,看起来GMapsFx忽略其中一个半径并绘制圆弧。
以下代码段的结果:
double centerLat = 31.166724;
double centerLong = 34.793119;
double latDelta = 0.5;
double longDelta = 0.01;
LatLong centreP = new LatLong(centerLat, centerLong);
LatLong start = new LatLong(centerLat, centerLong + longDelta);
LatLong end= new LatLong(centerLat + latDelta, centerLong);
MVCArray p= ArcBuilder.buildArcPoints(centreP, end, start);
com.lynden.gmapsfx.shapes.Polyline pp = new com.lynden.gmapsfx.shapes.Polyline();
pp.setPath(p);
map.addMapShape(pp);
出现在下图中。
消化数字:
中心:31.166724,34.793119
开始于:31.166724,34.803119
结束:31.666724,34.793119
你可以看到end
和center
彼此非常接近(我们应该得到一个非常高而窄的弧),弧实际上在东边开始很远,给出四分之一圈。
答案 0 :(得分:1)
ArcBuilder
仅使用一个半径;开始和结束LatLong
用于获取弧的起点和终点的方位。因此,它不能用于绘制椭圆。
由于库不提供椭圆形状,我改为写了EllipseBuilder
类:
import com.lynden.gmapsfx.javascript.object.LatLong;
import com.lynden.gmapsfx.javascript.object.MVCArray;
public class EllipseBuilder {
private static final int DEFAULT_ELLIPSE_POINTS = 10000;
/**
* Generates the points for an ellipse based on two radii from a center point.
*
* @param center
* The LatLong point of the center.
* @param longRadius
* longitude radius in meters
* @param latRadius
* latitude radius in meters
* @return An array of LatLong points in an MVC array representing the ellipse.
*/
public static final MVCArray buildEllipsePoints(LatLong center, double longRadius, double latRadius) {
return buildEllipsePoints(center, longRadius, latRadius, 0.);
}
/**
* Generates the points for an ellipse based on two radii from a center point and a counter clockwise rotation angle.
*
* @param center
* The LatLong point of the center.
* @param longRadius
* longitude radius in meters
* @param latRadius
* latitude radius in meters
* @param rotAngle
* rotation angle in degree, counter clockwise
* @return An array of LatLong points in an MVC array representing the ellipse.
*/
public static final MVCArray buildEllipsePoints(LatLong center, double longRadius, double latRadius, double rotAngle) {
int points = DEFAULT_ELLIPSE_POINTS;
MVCArray res = new MVCArray();
double longRadiusSquared = longRadius * longRadius;
double latRadiusSquared = latRadius * latRadius;
double radiiProduct = longRadius * latRadius;
double theta = 0d;
double angleIncrement = 360.0 / points;
for (int i = 0; (i < points + 1); i++) {
theta = i * angleIncrement;
double r = radiiProduct / (Math.sqrt(latRadiusSquared * Math.pow(Math.sin(Math.toRadians(theta)), 2)
+ longRadiusSquared * Math.pow(Math.cos(Math.toRadians(theta)), 2)));
res.push(center.getDestinationPoint(theta - rotAngle, r));
}
return res;
}
}
使用以下代码调用
double centerLat = 31.166724;
double centerLong = 34.793119;
double latDelta = 0.5;
double longDelta = 0.01;
LatLong centreP = new LatLong(centerLat, centerLong);
LatLong start = new LatLong(centerLat, centerLong + longDelta);
LatLong end = new LatLong(centerLat + latDelta, centerLong);
double longRadius = centreP.distanceFrom(start);
double latRadius = centreP.distanceFrom(end);
MVCArray p = EllipseBuilder.buildEllipsePoints(centreP, longRadius, latRadius);
com.lynden.gmapsfx.shapes.Polyline pp = new com.lynden.gmapsfx.shapes.Polyline();
pp.setPath(p);
map.addMapShape(pp);
// Add markers to the map
MarkerOptions markerOptionsStart = new MarkerOptions();
markerOptionsStart.position(start).visible(Boolean.TRUE).title("Start").label("S");
Marker markerStart = new Marker(markerOptionsStart);
map.addMarker(markerStart);
MarkerOptions markerOptionsEnd = new MarkerOptions();
markerOptionsEnd.position(end).visible(Boolean.TRUE).title("End").label("E");
Marker markerEnd = new Marker(markerOptionsEnd);
map.addMarker(markerEnd);
生成此图片:
要绘制旋转的椭圆,请添加度数角度。椭圆将以逆时针方向旋转:
double longRadius = centreP.distanceFrom(start);
double latRadius = centreP.distanceFrom(end);
double rotAngle = 20.;
MVCArray p = EllipseBuilder.buildEllipsePoints(centreP, longRadius, latRadius, rotAngle);
椭圆旋转20度,逆时针旋转:
我使用标记来标记起点和终点。
因为在你的情况下椭圆非常窄,我对DEFAULT_ELLIPSE_POINTS
使用了非常高的值。根据用例,此值应该更小,因此将其设置为参数而不是静态变量可能很有用。