I am getting latitudes and longitudes from json and i want to show them on a map. I've done it using normal way like by using googleMap and Overlays. but actually i want it to be like below image.
I've searched and got some hints like showing map in webView and using Javascript. but don't find any tutorial or sample code.
Its a static image and will not be zoom in or out. just i wants to put location coordinates on image.
so my question is, is that possible to have an image as a gooleMap?
thanks in advance.
I suggest you to override ImageView#onDraw() and draw location points on top of an image. The main task is to translate coordinates from geo space to ImageView space. Therefore, you need to know bounds of your map image in geo space.
I made a screenshot of USA in Google Maps. Using Right click -> What is here?
menu I found geo bounds of my screenshot. Also I picked some test points around the country border.
Here's a simple example. Custom ImageView:
public class MapImageView extends ImageView {
private float latitudeTop, latitudeBottom, longitudeRight, longitudeLeft;
private List<Float> points = new ArrayList<Float>();
private Paint pointPaint;
private Matrix pointMatrix = new Matrix();
public MapImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
pointPaint = new Paint();
pointPaint.setAntiAlias(true);
pointPaint.setStrokeCap(Cap.ROUND);
pointPaint.setColor(Color.RED);
pointPaint.setStrokeWidth(8.0f);
}
public void setBounds(float latitudeTop, float latitudeBottom, float longitudeLeft, float longitudeRight) {
this.latitudeTop = latitudeTop;
this.latitudeBottom = latitudeBottom;
this.longitudeLeft = longitudeLeft;
this.longitudeRight = longitudeRight;
}
public void addPoint(float latitude, float longitude) {
points.add(longitude);
points.add(latitude);
invalidate();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
pointMatrix.reset();
pointMatrix.postTranslate(-longitudeLeft, -latitudeTop);
pointMatrix.postScale(
getMeasuredWidth()/(longitudeRight-longitudeLeft),
getMeasuredHeight()/(latitudeBottom-latitudeTop));
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawPoints(mapPoints(), pointPaint);
}
private float[] mapPoints() {
float[] pts = new float[points.size()];
for (int i = 0; i < points.size(); i++) {
pts[i] = points.get(i);
}
pointMatrix.mapPoints(pts);
return pts;
}
}
In your layout:
<com.example.stackoverflow.MapImageView
android:id="@+id/img_map"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/map"
android:scaleType="fitXY" />
Note that scaleType="fitXY"
is important, because coordinates are mapped to ImageView bounds, not the map picture.
In your activity:
MapImageView mapView = (MapImageView)findViewById(R.id.img_map);
mapView.setBounds(52.734778f, 19.979026f, -130.78125f, -62.402344f);
mapView.addPoint(42.163403f,-70.839844f);
mapView.addPoint(42.163403f,-70.839844f);
Result:
If you are willing to move outside of Google Maps, I would suggest you give a try to jVector Map, a JavaScript based maps solution using jQuery.
Below is the code sample, that shows the unemployment rate in US:
The below Source Code will help you get this output:
$(function(){
$.getJSON('/data/us-unemployment.json', function(data){
var val = 2009;
statesValues = jvm.values.apply({}, jvm.values(data.states)),
metroPopValues = Array.prototype.concat.apply([], jvm.values(data.metro.population)),
metroUnemplValues = Array.prototype.concat.apply([], jvm.values(data.metro.unemployment));
$('#world-map-gdp').vectorMap({
map: 'us_aea_en',
markers: data.metro.coords,
series: {
markers: [{
attribute: 'fill',
scale: ['#FEE5D9', '#A50F15'],
values: data.metro.unemployment[val],
min: jvm.min(metroUnemplValues),
max: jvm.max(metroUnemplValues)
},{
attribute: 'r',
scale: [5, 20],
values: data.metro.population[val],
min: jvm.min(metroPopValues),
max: jvm.max(metroPopValues)
}],
regions: [{
scale: ['#DEEBF7', '#08519C'],
attribute: 'fill',
values: data.states[val],
min: jvm.min(statesValues),
max: jvm.max(statesValues)
}]
},
onMarkerLabelShow: function(event, label, index){
label.html(
''+data.metro.names[index]+''+
'Population: '+data.metro.population[val][index]+''+
'Unemployment rate: '+data.metro.unemployment[val][index]+'%'
);
},
onRegionLabelShow: function(event, label, code){
label.html(
''+label.html()+''+
'Unemployment rate: '+data.states[val][code]+'%'
);
}
});
var mapObject = $('#world-map-gdp').vectorMap('get', 'mapObject');
$("#slider").slider({
value: val,
min: 2005,
max: 2009,
step: 1,
slide: function( event, ui ) {
val = ui.value;
mapObject.series.regions[0].setValues(data.states[ui.value]);
mapObject.series.markers[0].setValues(data.metro.unemployment[ui.value]);
mapObject.series.markers[1].setValues(data.metro.population[ui.value]);
}
});
});
});
The Above Code will render the map like below:
LINK TO JVECTORMAP
Isn't this just a scaling issue?
Put a flat image in, and then plot the points exactly as you would normally but scaled.
Ie.
h_scale=(real_america_width/image_america_width)
v_scale=(real_america_height/image_america_height)
lat = lat_from_json*h_scale)
lon = lon_from_json*v_scale)
Then just plonk the markers.
Sorry it isn't real code but I have no idea what language you want it in. End of the day, it's a fairly simple method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With