在视图上绘制折线时坐标比例不正确 [英] Coordinates scale not correct when drawing a polyline on an View
问题描述
我想在视图
上绘制折线
。我不想在 MapView
上绘制它,因为我只希望 polyline
没有任何背景。
I want to draw a polyline
on a view
. I don't want to draw it on a MapView
because I only want the polyline
without any background.
我有折线
坐标,也有边界(东北和西南坐标)。
I have the polyline
coordinates and I also have its bounds (northeast and southwest coordinates).
想法是创建一个自定义的视图
并在其中绘制路径。我相信我遇到的问题是秤的问题。我可以将 LatLng
坐标转换为 x
和 y
坐标但是视图
上显示的折线太小。 视图
的宽度和高度设置为 64dp
。
The idea was to create a custom view
and draw the path there. The problem I believe I'm having is with the scale. I can convert the LatLng
coordinates to x
and y
coordinates but the polyline that is shown on the view
is too small. The view
is set with a 64dp
width and height.
这是我在做什么:
public PolylineView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
polylineSize = (int) context.getResources().getDimension(R.dimen.polyline_size);
setupAttributes(attrs);
}
private void setupAttributes(AttributeSet attrs) {
// Obtain a typed array of attributes
TypedArray a = getContext().getTheme().obtainStyledAttributes(attrs, R.styleable.PolylineView, 0, 0);
// Extract custom attributes into member variables
try {
polylineColor = a.getColor(R.styleable.PolylineView_polylineColor, Color.BLACK);
} finally {
// TypedArray objects are shared and must be recycled.
a.recycle();
}
polyline = new Paint(Paint.ANTI_ALIAS_FLAG);
polyline.setAntiAlias(true);
polyline.setStyle(Paint.Style.STROKE);
polyline.setStrokeWidth(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2, getResources().getDisplayMetrics()));
polyline.setStrokeCap(Paint.Cap.ROUND);
polyline.setColor(polylineColor);
path = new Path();
smp = new SphericalMercatorProjection(polylineSize);
}
@Override protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
point = smp.toPoint(polylineCoordinates.get(0));
path.moveTo((float) (point.x * scale), (float) (point.y * scale));
for (int i = 1; i < polylineCoordinates.size(); i++) {
point = smp.toPoint(polylineCoordinates.get(i));
path.lineTo((float) (point.x * scale), (float) (point.y * scale));
}
canvas.drawPath(path, polyline);
}
public void setPolyline(List<LatLng> polylineCoordinates, RealmLatLngBounds polylineBounds) {
this.polylineBounds = polylineBounds;
this.polylineCoordinates = polylineCoordinates;
//Find the scale
Point northeast = smp.toPoint(polylineBounds.getNortheast());
Point southwest = smp.toPoint(polylineBounds.getSouthwest());
scale = polylineSize / Math.max(Math.max(northeast.x, southwest.x), Math.max(northeast.y, southwest.y));
invalidate();
requestLayout();
}
之后可以转换折线
坐标以便使用视图
的完整大小?
After can I transform the polyline
coordinates so that the full size of the view
is used?
编辑:
我能看到的问题之一是当转换为 x
和 y
,值是两个接近(精确)的
One of the problems that I can see is when converting to x
and y
, values are two close (precision)
推荐答案
在@pskink的帮助下,我设法实现了这一目标
With the help of @pskink I've managed to achieve this
private int polylineSize;
private Paint polyline;
private SphericalMercatorProjection smp;
PointF northeast;
PointF[] points;
PointF southwest;
Path originalPath;
Path transformedPath;
public PolylineView(Context context) {
super(context);
}
public PolylineView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
polylineSize = (int) context.getResources().getDimension(R.dimen.polyline_size);
setupAttributes(attrs);
}
public PolylineView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
polylineSize = (int) context.getResources().getDimension(R.dimen.polyline_size);
setupAttributes(attrs);
}
private void setupAttributes(AttributeSet attrs) {
// Obtain a typed array of attributes
TypedArray a = getContext().getTheme().obtainStyledAttributes(attrs, R.styleable.PolylineView, 0, 0);
// Extract custom attributes into member variables
int polylineColor;
try {
polylineColor = a.getColor(R.styleable.PolylineView_polylineColor, Color.BLACK);
} finally {
// TypedArray objects are shared and must be recycled.
a.recycle();
}
polyline = new Paint(Paint.ANTI_ALIAS_FLAG);
polyline.setAntiAlias(true);
polyline.setStyle(Paint.Style.STROKE);
polyline.setStrokeWidth(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2, getResources().getDisplayMetrics()));
polyline.setStrokeCap(Paint.Cap.ROUND);
polyline.setColor(polylineColor);
smp = new SphericalMercatorProjection(polylineSize);
}
public void setPolylineData(List<LatLng> polylineCoordinates, RealmLatLngBounds polylineBounds) {
originalPath = new Path();
transformedPath = new Path();
Point point = smp.toPoint(polylineBounds.getNortheast());
northeast = new PointF((float) point.x, (float) point.y);
point = smp.toPoint(polylineBounds.getSouthwest());
southwest = new PointF((float) point.x, (float) point.y);
points = new PointF[polylineCoordinates.size()];
for (int i = 0; i < polylineCoordinates.size(); i++) {
point = smp.toPoint(polylineCoordinates.get(i));
points[i] = new PointF((float) point.x, (float) point.y);
}
originalPath.moveTo(points[0].x, points[0].y);
for (PointF p : points) {
originalPath.lineTo(p.x, p.y);
}
RectF src = new RectF(southwest.x, northeast.y, northeast.x, southwest.y);
RectF dst = new RectF(0, 0, polylineSize, polylineSize);
Matrix matrix = new Matrix();
matrix.setRectToRect(src, dst, Matrix.ScaleToFit.CENTER);
originalPath.transform(matrix, transformedPath);
invalidate();
requestLayout();
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawPath(transformedPath, polyline);
}
此视图用于 RecyclerView
并将数据设置在 onBindViewHolder
This view is used on a RecyclerView
and the data is set on onBindViewHolder
这篇关于在视图上绘制折线时坐标比例不正确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!