2
A
回答
2
只需添加此代码..
googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
googleMap.getUiSettings().setZoomControlsEnabled(true);
googleMap.getUiSettings().setCompassEnabled(true);
googleMap.getUiSettings().setMyLocationButtonEnabled(true);
googleMap.getUiSettings().setAllGesturesEnabled(true);
googleMap.setMyLocationEnabled(true);
9
在API中有没有方法来设置比例尺。在这种情况下,你应该自己实现它。这是你如何做到这一点的简单例子。我已将来自答案How to add a map scale in MapView on Android?的代码调整为适用于GoogleMap。
RelativeLayout container = (RelativeLayout) findViewById(R.id.main_view);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(800, 800);
params.addRule(RelativeLayout.CENTER_HORIZONTAL);
params.addRule(RelativeLayout.CENTER_VERTICAL);
mScaleBar = new ScaleBar(this, mMap);
mScaleBar.setLayoutParams(params);
希望这将是为别人有用:
class ScaleBar extends ImageView {
float mXOffset = 10;
float mYOffset = 10;
float mLineWidth = 3;
int mTextSize = 25;
boolean mIsImperial = false;
boolean mIsNautical = false;
boolean mIsLatitudeBar = true;
boolean mIsLongitudeBar = true;
private GoogleMap mMap;
float mXdpi;
float mYdpi;
public ScaleBar(Context context, GoogleMap map) {
super(context);
mMap = map;
mXdpi = context.getResources().getDisplayMetrics().xdpi;
mYdpi = context.getResources().getDisplayMetrics().ydpi;
}
@Override
public void onDraw(Canvas canvas) {
canvas.save();
drawScaleBarPicture(canvas);
canvas.restore();
}
private void drawScaleBarPicture(Canvas canvas) {
// 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 = mMap.getProjection();
if (projection == null) {
return;
}
final Paint barPaint = new Paint();
barPaint.setColor(Color.BLACK);
barPaint.setAntiAlias(true);
barPaint.setStrokeWidth(mLineWidth);
final Paint textPaint = new Paint();
textPaint.setColor(Color.BLACK);
textPaint.setAntiAlias(true);
textPaint.setTextSize(mTextSize);
drawXMetric(canvas, textPaint, barPaint);
drawYMetric(canvas, textPaint, barPaint);
}
private void drawXMetric(Canvas canvas, Paint textPaint, Paint barPaint) {
Projection projection = mMap.getProjection();
if (projection != null) {
LatLng p1 = projection.fromScreenLocation(new Point((int) ((getWidth()/2) - (mXdpi/2)), getHeight()/2));
LatLng p2 = projection.fromScreenLocation(new Point((int) ((getWidth()/2) + (mXdpi/2)), getHeight()/2));
Location locationP1 = new Location("ScaleBar location p1");
Location locationP2 = new Location("ScaleBar location p2");
locationP1.setLatitude(p1.latitude);
locationP2.setLatitude(p2.latitude);
locationP1.setLongitude(p1.longitude);
locationP2.setLongitude(p2.longitude);
float xMetersPerInch = locationP1.distanceTo(locationP2);
if (mIsLatitudeBar) {
String xMsg = scaleBarLengthText(xMetersPerInch, mIsImperial, mIsNautical);
Rect xTextRect = new Rect();
textPaint.getTextBounds(xMsg, 0, xMsg.length(), xTextRect);
int textSpacing = (int) (xTextRect.height()/5.0);
canvas.drawRect(mXOffset, mYOffset, mXOffset + mXdpi, mYOffset + mLineWidth, barPaint);
canvas.drawRect(mXOffset + mXdpi, mYOffset, mXOffset + mXdpi + mLineWidth, mYOffset +
xTextRect.height() + mLineWidth + textSpacing, barPaint);
if (!mIsLongitudeBar) {
canvas.drawRect(mXOffset, mYOffset, mXOffset + mLineWidth, mYOffset +
xTextRect.height() + mLineWidth + textSpacing, barPaint);
}
canvas.drawText(xMsg, (mXOffset + mXdpi/2 - xTextRect.width()/2),
(mYOffset + xTextRect.height() + mLineWidth + textSpacing), textPaint);
}
}
}
private void drawYMetric(Canvas canvas, Paint textPaint, Paint barPaint) {
Projection projection = mMap.getProjection();
if (projection != null) {
Location locationP1 = new Location("ScaleBar location p1");
Location locationP2 = new Location("ScaleBar location p2");
LatLng p1 = projection.fromScreenLocation(new Point(getWidth()/2,
(int) ((getHeight()/2) - (mYdpi/2))));
LatLng p2 = projection.fromScreenLocation(new Point(getWidth()/2,
(int) ((getHeight()/2) + (mYdpi/2))));
locationP1.setLatitude(p1.latitude);
locationP2.setLatitude(p2.latitude);
locationP1.setLongitude(p1.longitude);
locationP2.setLongitude(p2.longitude);
float yMetersPerInch = locationP1.distanceTo(locationP2);
if (mIsLongitudeBar) {
String yMsg = scaleBarLengthText(yMetersPerInch, mIsImperial, mIsNautical);
Rect yTextRect = new Rect();
textPaint.getTextBounds(yMsg, 0, yMsg.length(), yTextRect);
int textSpacing = (int) (yTextRect.height()/5.0);
canvas.drawRect(mXOffset, mYOffset, mXOffset + mLineWidth, mYOffset + mYdpi, barPaint);
canvas.drawRect(mXOffset, mYOffset + mYdpi, mXOffset + yTextRect.height() +
mLineWidth + textSpacing, mYOffset + mYdpi + mLineWidth, barPaint);
if (!mIsLatitudeBar) {
canvas.drawRect(mXOffset, mYOffset, mXOffset + yTextRect.height() +
mLineWidth + textSpacing, mYOffset + mLineWidth, barPaint);
}
float x = mXOffset + yTextRect.height() + mLineWidth + textSpacing;
float y = mYOffset + mYdpi/2 + yTextRect.width()/2;
canvas.rotate(-90, x, y);
canvas.drawText(yMsg, x, y + textSpacing, textPaint);
}
}
}
private String scaleBarLengthText(float meters, boolean imperial, boolean nautical) {
if (this.mIsImperial) {
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.mIsNautical) {
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";
}
}
}
}
然后你就可以用这种方式添加到您的布局。
0
如前所述,Google Maps API中没有提及比例尺。一个人需要自己编程一个人。我从ArkadiuszCieśliński那里得到了答案,并加强了这一点,以获得更多Google地图,例如缩放视图。
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.location.Location;
import android.support.v7.widget.AppCompatImageView;
import android.util.AttributeSet;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.Projection;
import com.google.android.gms.maps.model.LatLng;
import java.util.Locale;
import thermcam.georg.locationhistoryviewer.R;
import thermcam.georg.locationhistoryviewer.util.ResourcesUtil;
/**
* Created by georg on 18.04.17.
*/
public class MapScaleBar extends AppCompatImageView{
public enum ColorMode {
COLOR_MODE_AUTO,
COLOR_MODE_DARK,
COLOR_MODE_WHITE
}
private static final int FT_IN_MILE = 5280;
private static final int[] METERS = {1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000,
10000, 20000, 50000, 100000, 200000, 500000, 1000000, 2000000};
private static final int[] FT = {1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000,
FT_IN_MILE, 2 * FT_IN_MILE, 5 * FT_IN_MILE, 10 * FT_IN_MILE, 20 * FT_IN_MILE, 50 * FT_IN_MILE,
100 * FT_IN_MILE, 200 * FT_IN_MILE, 500 * FT_IN_MILE, 1000 * FT_IN_MILE, 2000 * FT_IN_MILE};
float mXOffset = 10; // in px
float mYOffset = 10; // in px
private float mLineWidth = 4; // in dp
private float mTextSize = 15; // in dp
private float mTextPadding = 2; // in dp
public ColorMode mColorMode = ColorMode.COLOR_MODE_AUTO;
private GoogleMap mMap;
float mXdpi;
float mYdpi;
public MapScaleBar(Context context) {
this(context, null);
}
public MapScaleBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MapScaleBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mXdpi = context.getResources().getDisplayMetrics().xdpi;
mYdpi = context.getResources().getDisplayMetrics().ydpi;
setLineWidth(mLineWidth);
setTextSize(mTextSize);
setTextPadding(mTextPadding);
}
public void addTarget(GoogleMap map) {
this.mMap = map;
map.setOnCameraMoveListener(new GoogleMap.OnCameraMoveListener() {
@Override
public void onCameraMove() {
invalidate();
}
});
}
public void setLineWidth(float lineWidth) {
this.mLineWidth = pxToDp(lineWidth);
}
public void setTextSize(float textSize) {
this.mTextSize = pxToDp(textSize);
}
public void setTextPadding(float textPadding) {
this.mTextPadding = pxToDp(textPadding);
}
public float pxToDp(float px) {
return px * (mYdpi/160);
}
@Override
public void onDraw(Canvas canvas) {
if (mMap == null)
return;
canvas.save();
drawScaleBarPicture(canvas);
canvas.restore();
}
private void drawScaleBarPicture(Canvas canvas) {
// 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.
int darkC = ResourcesUtil.getColor(getResources(), R.color.textDarkPrimary, null);
int whiteC = ResourcesUtil.getColor(getResources(), R.color.textLightPrimary, null);
if (mColorMode == ColorMode.COLOR_MODE_WHITE ||
mColorMode == ColorMode.COLOR_MODE_AUTO && (mMap.getMapType() == GoogleMap.MAP_TYPE_SATELLITE || mMap.getMapType() == GoogleMap.MAP_TYPE_HYBRID))
drawXMetric(canvas, whiteC, darkC);
else
drawXMetric(canvas, darkC, whiteC);
}
private void drawXMetric(Canvas canvas, int fillColor, int outlineColor) {
Projection projection = mMap.getProjection();
LatLng p1 = projection.fromScreenLocation(new Point(
(int) ((getWidth()/2) - (mXdpi/2)), getHeight()/2));
LatLng p2 = projection.fromScreenLocation(new Point((int) (
(getWidth()/2) + (mXdpi/2)), getHeight()/2));
Location locationP1 = new Location("ScaleBar location p1");
Location locationP2 = new Location("ScaleBar location p2");
locationP1.setLatitude(p1.latitude);
locationP2.setLatitude(p2.latitude);
locationP1.setLongitude(p1.longitude);
locationP2.setLongitude(p2.longitude);
// PAINTS
final Paint barPaintFill = new Paint(Paint.ANTI_ALIAS_FLAG);
barPaintFill.setStyle(Paint.Style.FILL);
barPaintFill.setColor(fillColor);
final Paint barPaintStroke = new Paint(barPaintFill);
barPaintStroke.setColor(outlineColor);
barPaintStroke.setStyle(Paint.Style.STROKE);
barPaintStroke.setStrokeWidth(mLineWidth/5);
final Paint textPaintFill = new Paint(barPaintFill);
textPaintFill.setTextSize(mTextSize);
final Paint textPaintStroke = new Paint(barPaintStroke);
textPaintStroke.setTextSize(mTextSize);
// LENGTH
float xMetersPerInch = locationP1.distanceTo(locationP2);
int nearestM = findNextSmallestInUnit(xMetersPerInch, false);
int nearestFT = findNextSmallestInUnit(xMetersPerInch, true);
float lengthM = mXdpi/xMetersPerInch * nearestM;
float lengthFT = mXdpi/xMetersPerInch * (nearestFT/3.2808f);
String msgM = scaleBarLengthText(nearestM, false);
String msgFT = scaleBarLengthText(nearestFT, true);
float longest = Math.max(lengthFT, lengthM);
// Get text rects & cords
Rect textRectM = new Rect();
textPaintFill.getTextBounds(msgM, 0, msgM.length(), textRectM);
Rect textRectFT = new Rect();
textPaintFill.getTextBounds(msgFT, 0, msgFT.length(), textRectFT);
PointF textCoordM = new PointF(canvas.getWidth() - mXOffset - textRectM.width() - mTextPadding,
canvas.getHeight() - mYOffset - textRectFT.height() - mTextPadding * 2 - mLineWidth);
PointF textCoordFT = new PointF(canvas.getWidth() - mXOffset - textRectFT.width() - mTextPadding,
canvas.getHeight() - mYOffset - textRectFT.height() - textRectFT.top);
// PointF textCoordFT = new PointF()
// All movements are based in the bottom, right corner
Path barP = new Path();
barP.setFillType(Path.FillType.EVEN_ODD);
barP.moveTo(canvas.getWidth() - mXOffset, canvas.getHeight() - mYOffset - textRectFT.height() - mTextPadding);
barP.rLineTo(- lengthFT + mLineWidth, 0);
barP.rLineTo(0, textRectFT.height() * 0.6f);
barP.rLineTo(- mLineWidth, 0);
barP.rLineTo(0, -textRectFT.height() * 0.6f);
barP.rLineTo(lengthFT - longest, 0);
barP.rLineTo(0, - mLineWidth);
barP.rLineTo(longest - lengthM, 0);
barP.rLineTo(0, -textRectM.height() * 0.6f);
barP.rLineTo(mLineWidth, 0);
barP.rLineTo(0, textRectM.height() * 0.6f);
barP.rLineTo(lengthM - mLineWidth, 0);
barP.close();
canvas.drawPath(barP, barPaintFill);
canvas.drawPath(barP, barPaintStroke);
canvas.drawText(msgM, textCoordM.x, textCoordM.y, textPaintStroke);
canvas.drawText(msgM, textCoordM.x, textCoordM.y, textPaintFill);
canvas.drawText(msgFT, textCoordFT.x, textCoordFT.y, textPaintStroke);
canvas.drawText(msgFT, textCoordFT.x, textCoordFT.y, textPaintFill);
}
private int findNextSmallestInUnit(float meters, boolean imperial) {
int[] data = imperial ? FT : METERS;
float value = meters * (imperial ? 3.2808f : 1);
int closest = data[0];
for (int elem: data) {
if (elem - value > 0)
break;
else
closest = elem;
}
return closest;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension((int)mXdpi, (int)(mTextPadding * 4 + mTextSize * 2 + mLineWidth));
}
private String scaleBarLengthText(int value, boolean imperial) {
if (imperial) {
if (value >= FT_IN_MILE)
return String.format(Locale.getDefault(), "%d mi", value/FT_IN_MILE);
else
return String.format(Locale.getDefault(), "%d ft", value);
} else {
if (value >= 1000)
return String.format(Locale.getDefault(), "%d km", value/1000);
else
return String.format(Locale.getDefault(), "%d m", value);
}
}
}
并可以使用它,将它添加到您的layout.xml
。例如像这样:
<package.id.MapScaleBar
android:id="@+id/scaleBar"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
然后,您只需要在它的addTarget
方法onMapReady(GoogleMap googleMap)
功能添加谷歌地图实例,例如。
MapScaleBar scaleBar = (MapScaleBar)findViewById(R.id.scaleBar);
scaleBar.mColorMode = MapScaleBar.ColorMode.COLOR_MODE_DARK; // normal
scaleBar.mColorMode = MapScaleBar.ColorMode.COLOR_MODE_WHITE; // inverted
scaleBar.mColorMode = MapScaleBar.ColorMode.COLOR_MODE_AUTO; // detect automatically after Google Map style
scaleBar.addTarget(mMap);
1
我已经根据以前的答案创建了一个小型图书馆。
https://github.com/pengrad/MapScaleView
添加依赖
compile 'com.github.pengrad:mapscaleview:1.2.0'
包括布局在地图
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/mapFragment"
class="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<com.github.pengrad.mapscaleview.MapScaleView
android:id="@+id/scaleView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="4dp"/>
</FrameLayout>
更新代码
MapScaleView scaleView = (MapScaleView) findViewById(R.id.scaleView);
CameraPosition cameraPosition = map.getCameraPosition();
// need to pass zoom and latitude
scaleView.update(cameraPosition.zoom, cameraPosition.target.latitude);
相关问题
- 1. 如何在android v2上显示地图比例尺地图
- 2. 如何在地图上显示点的图例(比例尺颜色)?
- 3. 在地图上显示比例尺查看
- 4. 如何在Google地图上选择正确的缩放比例
- 5. 如何在MKMapView缩放期间显示地图比例,如Apple的Maps.app
- 6. Choropleth地图比例尺和图例
- 7. 如何制作Google地图缩放控件将自动显示?
- 8. D3缩放比例尺地图,而不是点
- 9. 如何在地图控件上直接添加比例尺或北向箭头?
- 10. Android - 计算每个缩放级别的地图距离,比如Gmaps比例尺
- 11. iPhone 4和iPhone 5上不同的地图缩放比例
- 12. Android:为地图设置缩放比例
- 13. 如何缩放svg地图以在网络上显示
- 14. 安卓缩放比例尺限制
- 15. 如何控制刻面ggplot2图的纵横比和比例尺?
- 16. d3.js - 缩放和点击中心 - 地图比例尺,点不要
- 17. 如何确保缩放控件始终显示在MapView上?
- 18. 如何启用缩放控件并缩小WebView中的缩放比例?
- 19. Highmaps地图比例尺
- 20. 在Android画布中设置显示图像的缩放比例
- 21. 如何在WebBrowser控件中显示和缩放YouTube媒体?
- 22. 如何停止比例图像缩放?
- 23. 如何在Android上的MapView中添加地图比例尺?
- 24. Google Maps API;如何在地图上添加比例尺度?
- 25. 在Android上保持画布比例和缩放比例
- 26. 谷歌地图v3缩放控件没有显示
- 27. 谷歌地图缩放控件无法正确显示
- 28. 显示Google地图的UIWebView会切断缩放控件
- 29. 比例图像缩放
- 30. Window.open图像和缩放比例
的伟大工程。一个只是要添加一些onTouch处理程序,并添加mScaleBar.invalidate()在类的构造函数 – dariusiv
@dariusiv您可以添加下一个代码无效的观点: 'mMap.setOnCameraMoveListener(新GoogleMap.OnCameraMoveListener(){ @覆盖 public void onCameraMove(){ invalidate(); } }); – ClarkXP