- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在努力添加一个 map 比例,该比例根据当前缩放级别在屏幕上显示当前长度。我有一种感觉,它可能存在一些预定义的类来使用,但我不知道......?我到处搜索但找不到任何东西。
我非常感谢任何帮助 =)
//亚历克斯
最佳答案
好的,我知道了!路易斯的回答对我和 OpenStreetMap 帮助很大。这是我想出的:
<your.own.package.path>;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Picture;
import android.graphics.Rect;
import android.location.Location;
import android.util.Log;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.Projection;
import com.iqqn.uppgift5.GameMapActivity;
public class ScaleBarOverlay extends Overlay{
// ===========================================================
// Fields
// ===========================================================
// Defaults
boolean enabled = true;
float xOffset = 10;
float yOffset = 10;
float lineWidth = 2;
int textSize = 12;
boolean imperial = false;
boolean nautical = false;
boolean latitudeBar = true;
boolean longitudeBar = false;
// Internal
protected final MapView mapView;
protected final GameMapActivity master;
private Context context;
protected final Picture scaleBarPicture = new Picture();
private final Matrix scaleBarMatrix = new Matrix();
private int lastZoomLevel = -1;
float xdpi;
float ydpi;
int screenWidth;
int screenHeight;
// ===========================================================
// Constructors
// ===========================================================
public ScaleBarOverlay(Context _context, GameMapActivity master, MapView mapView) {
super();
this.master = master;
this.context = _context;
this.mapView = mapView;
xdpi = this.context.getResources().getDisplayMetrics().xdpi;
ydpi = this.context.getResources().getDisplayMetrics().ydpi;
screenWidth = this.context.getResources().getDisplayMetrics().widthPixels;
screenHeight = this.context.getResources().getDisplayMetrics().heightPixels;
}
// ===========================================================
// Getter & Setter
// ===========================================================
/**
* @return the enabled
*/
public boolean isEnabled() {
return enabled;
}
/**
* @param enabled the enabled to set
*/
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
/**
* @return the lineWidth
*/
public float getLineWidth() {
return lineWidth;
}
/**
* @param lineWidth the lineWidth to set
*/
public void setLineWidth(float lineWidth) {
this.lineWidth = lineWidth;
}
/**
* @return the imperial
*/
public boolean isImperial() {
return imperial;
}
/**
* @param imperial the imperial to set
*/
public void setImperial() {
this.imperial = true;
this.nautical = false;
createScaleBarPicture();
}
/**
* @return the nautical
*/
public boolean isNautical() {
return nautical;
}
/**
* @param nautical the nautical to set
*/
public void setNautical() {
this.nautical = true;
this.imperial = false;
createScaleBarPicture();
}
public void setMetric() {
this.nautical = false;
this.imperial = false;
createScaleBarPicture();
}
public void drawLatitudeScale(boolean latitude) {
this.latitudeBar = latitude;
}
public void drawLongitudeScale(boolean longitude) {
this.longitudeBar = longitude;
}
@Override
public void draw(Canvas canvas, MapView localMapView, boolean shadow) {
if (this.enabled) {
// Draw the overlay
if (shadow == false) {
final int zoomLevel = localMapView.getZoomLevel();
if (zoomLevel != lastZoomLevel) {
lastZoomLevel = zoomLevel;
createScaleBarPicture();
}
this.scaleBarMatrix.setTranslate(-1 * (scaleBarPicture.getWidth() / 2 - 0.5f), -1 * (scaleBarPicture.getHeight() / 2 - 0.5f));
this.scaleBarMatrix.postTranslate(xdpi/2, ydpi/2 + canvas.getHeight()-50);
canvas.save();
canvas.setMatrix(scaleBarMatrix);
canvas.drawPicture(scaleBarPicture);
canvas.restore();
}
}
}
// ===========================================================
// Methods
// ===========================================================
public void disableScaleBar() {
this.enabled = false;
}
public boolean enableScaleBar() {
return this.enabled = true;
}
private void createScaleBarPicture() {
// We want the scale bar to be as long as the closest round-number miles/kilometers
// to 1-inch at the latitude at the current center of the screen.
Projection projection = mapView.getProjection();
if (projection == null) {
return;
}
Location locationP1 = new Location("ScaleBar location p1");
Location locationP2 = new Location("ScaleBar location p2");
// Two points, 1-inch apart in x/latitude, centered on screen
GeoPoint p1 = projection.fromPixels((int) ((screenWidth / 2) - (xdpi / 2)), screenHeight/2);
GeoPoint p2 = projection.fromPixels((int) ((screenWidth / 2) + (xdpi / 2)), screenHeight/2);
locationP1.setLatitude(p1.getLatitudeE6()/1E6);
locationP2.setLatitude(p2.getLatitudeE6()/1E6);
locationP1.setLongitude(p1.getLongitudeE6()/1E6);
locationP2.setLongitude(p2.getLongitudeE6()/1E6);
float xMetersPerInch = locationP1.distanceTo(locationP2);
p1 = projection.fromPixels(screenWidth/2, (int) ((screenHeight / 2) - (ydpi / 2)));
p2 = projection.fromPixels(screenWidth/2, (int) ((screenHeight / 2) + (ydpi / 2)));
locationP1.setLatitude(p1.getLatitudeE6()/1E6);
locationP2.setLatitude(p2.getLatitudeE6()/1E6);
locationP1.setLongitude(p1.getLongitudeE6()/1E6);
locationP2.setLongitude(p2.getLongitudeE6()/1E6);
float yMetersPerInch = locationP1.distanceTo(locationP2);
final Paint barPaint = new Paint();
barPaint.setColor(Color.BLACK);
barPaint.setAntiAlias(true);
barPaint.setStyle(Style.FILL);
barPaint.setAlpha(255);
final Paint textPaint = new Paint();
textPaint.setColor(Color.BLACK);
textPaint.setAntiAlias(true);
textPaint.setStyle(Style.FILL);
textPaint.setAlpha(255);
textPaint.setTextSize(textSize);
final Canvas canvas = scaleBarPicture.beginRecording((int)xdpi, (int)ydpi);
if (latitudeBar) {
String xMsg = scaleBarLengthText(xMetersPerInch, imperial, nautical);
Rect xTextRect = new Rect();
textPaint.getTextBounds(xMsg, 0, xMsg.length(), xTextRect);
int textSpacing = (int)(xTextRect.height() / 5.0);
canvas.drawRect(xOffset, yOffset, xOffset + xdpi, yOffset + lineWidth, barPaint);
canvas.drawRect(xOffset + xdpi, yOffset, xOffset + xdpi + lineWidth, yOffset + xTextRect.height() + lineWidth + textSpacing, barPaint);
if (!longitudeBar) {
canvas.drawRect(xOffset, yOffset, xOffset + lineWidth, yOffset + xTextRect.height() + lineWidth + textSpacing, barPaint);
}
canvas.drawText(xMsg, (xOffset + xdpi/2 - xTextRect.width()/2), (yOffset + xTextRect.height() + lineWidth + textSpacing), textPaint);
}
if (longitudeBar) {
String yMsg = scaleBarLengthText(yMetersPerInch, imperial, nautical);
Rect yTextRect = new Rect();
textPaint.getTextBounds(yMsg, 0, yMsg.length(), yTextRect);
int textSpacing = (int)(yTextRect.height() / 5.0);
canvas.drawRect(xOffset, yOffset, xOffset + lineWidth, yOffset + ydpi, barPaint);
canvas.drawRect(xOffset, yOffset + ydpi, xOffset + yTextRect.height() + lineWidth + textSpacing, yOffset + ydpi + lineWidth, barPaint);
if (! latitudeBar) {
canvas.drawRect(xOffset, yOffset, xOffset + yTextRect.height() + lineWidth + textSpacing, yOffset + lineWidth, barPaint);
}
float x = xOffset + yTextRect.height() + lineWidth + textSpacing;
float y = yOffset + ydpi/2 + yTextRect.width()/2;
canvas.rotate(-90, x, y);
canvas.drawText(yMsg, x, y + textSpacing, textPaint);
}
scaleBarPicture.endRecording();
}
private String scaleBarLengthText(float meters, boolean imperial, boolean nautical) {
if (this.imperial) {
if (meters >= 1609.344) {
return (meters / 1609.344) + "mi";
} else if (meters >= 1609.344/10) {
return ((meters / 160.9344) / 10.0) + "mi";
} else {
return (meters * 3.2808399) + "ft";
}
} else if (this.nautical) {
if (meters >= 1852) {
return ((meters / 1852)) + "nm";
} else if (meters >= 1852/10) {
return (((meters / 185.2)) / 10.0) + "nm";
} else {
return ((meters * 3.2808399)) + "ft";
}
} else {
if (meters >= 1000) {
return ((meters / 1000)) + "km";
} else if (meters > 100) {
return ((meters / 100.0) / 10.0) + "km";
} else {
return meters + "m";
}
}
}
@Override
public boolean onTap(GeoPoint point, MapView mapView) {
// Do not react to screen taps.
return false;
}
}
在您的 onCreate() 中按以下方式使用它:
...
scaleBarOverlay = new ScaleBarOverlay(this.getBaseContext(), this, myMapView);
List<Overlay> overlays = myMapView.getOverlays();
// Add scale bar overlay
scaleBarOverlay.setMetric();
overlays.add(scaleBarOverlay);
...
希望这对任何人都有帮助 =) 这将适用于 API 级别 7+。不过,我还没有在 API 级别 14+ 上测试过它,而且我知道一些硬件加速的东西“不能”在那里工作,就像用 Canvas 画图一样。但我认为它适用于录音。
再次感谢路易斯!
//亚历山大
关于java - 如何在 Android 的 MapView 中添加 map 比例尺?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12964608/
我已经开始尝试在 Canvas 对象上绘图。在过去,我对 Canvas 的接触一直以图像处理为中心 (NPI),因此我对它的坐标系和转换过程比较熟悉。我正在使用屏幕尺寸为 30 X 30 的测试 Ca
当 size 不是原生时,我希望有一个内联 svg 元素的内容缩放。当然,我可以将它作为一个单独的文件并像这样缩放它。 index.html: foo.svg: 但是,我想通过 CSS 向 SVG
我想知道如何在leafleat.js 中显示比例尺 map 。那就是:我想要这个 而不是这个 (带到 leaflet tutorial )。请参见图片的左下角。 最佳答案 您可以使用 L.contro
我遇到了一个问题,我相信很多 iOS 开发者以前都遇到过,所以我来这里寻求帮助。我在一家公司工作,我正在开发的 iPhone 应用程序的设计规范是在 Adobe PhotoShop 中制定的。我得
谷歌地图应用程序默认显示标尺/比例尺,当我们放大/缩小 map 时会出现。我想在我正在构建的 android 应用程序中显示一个类似的标尺。我正在使用 Google Map V2,但似乎没有任何可用的
我有一个从 0 到 275 的 UISlider。我想使用 slider 来缩放 UIImageView。 当我的 slider 值为 0 时,我的 UIImageView 应该具有原始大小(scal
使用 GeoTools 我能够使用 JMapPane 类显示一个简单的形状文件。我的要求是绘制一个类似于任何 map 的条形图,在我放大/缩小时显示 map 的比例尺(以米为单位)与条形图的长度相关。
在我的 Java 应用程序中,我使用 JmapViewer; map 绘制在 jPanel 上。是否可以获取当前缩放级别对应的 map 比例尺?该 map 基于著名的墨卡托投影: X = R * lo
我有一个托管 Google 地球插件实例的应用程序,我有兴趣获取 map 的当前比例并在我的应用程序中使用它。 我知道我可以使用 GEOptions 并设置比例图例可见性,但我想在我的应用程序中使用实
我的缩放级别为 3-21。分别缩小-放大。 但我想用给定的屏幕条(屏幕宽度?)来计算缩放级别到米/公里距离,就像 Gmaps 比例尺一样。 示例: 缩放级别 20 = 数百米 缩放级别 3 = 数千公
我正在努力添加一个 map 比例,该比例根据当前缩放级别在屏幕上显示当前长度。我有一种感觉,它可能存在一些预定义的类来使用,但我不知道......?我到处搜索但找不到任何东西。 我非常感谢任何帮助 =
我正在使用 Google API v2 map Android,但我无法在其上显示比例尺。请帮帮我,我能做些什么来在我的 map 上显示比例尺吗?我正在寻找它,但没有帮助。 最佳答案 Google 在
我正在寻求有关创建用于 D3.js 可缩放 map 的 map 比例尺的帮助。我经常使用 D3.js 为我的工作创建 map 。我从来没有在过去构建的 map 上放置比例尺,但最近我收到了在 map
我是一名优秀的程序员,十分优秀!