问题
In my app, i have recyclerview which contain imagview and this imageview contain static map image by using coordinates which i store in sqlite. and when i click on that image i am passing that coordinates in string array format to other map activity and then using this string array coordinates again draw the same polygon which static map hold into google map. but i don't understand how to do this.
I tried following code but not working:
this is code of my adapter class where i display static map on image view and then using intent pass the coordinates to map activity
String url ="https://maps.googleapis.com/maps/api/staticmap?";
url+="&zoom=18";
url+="&size=300x300";
url+="&maptype=satellite";
url+="&path=color:green|fillcolor:0xFFFF0033|"+ Coordinates;
url+="&key=" + "AIzaSyCj80x6E****Lx_KFsHKlogV0";
Picasso.get().load(url).into(holder.poly_image);
holder.poly_image.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(mCtx, EditMapsActivity.class);
i.putExtra("img", Poly_Coords);
mCtx.startActivity(i);
}
});
this is my map activity where i want to draw polygon using coordinates:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit_maps);
// Obtain the SupportMapFragment and get notified when the map is ready
to be used.
SupportMapFragment mapFragment = (SupportMapFragment)
getSupportFragmentManager().findFragmentById(R.id.mapView);
mapFragment.getMapAsync(EditMapsActivity.this);
Intent intent = getIntent();
String staticPolyCoords = intent.getStringExtra("img");
Log.d("Log", "Polygon Coords" + staticPolyCoords);
String answer = staticPolyCoords;
ArrayList<Location> arrayListLatLng = new ArrayList<>();
answer = answer.replace("lat/lng: (" , "");
answer = answer.replace(")" , "");
answer = answer.replace("]","");
answer = answer.replace("[","");
String[] arrayLatLng = answer.split(",");
Log.d("LOG_TAG", "Polygon Coordinates" + arrayLatLng);
for(int i = 0 ; i < arrayLatLng.length ; i++ ){
LatLng Cooordinate_Point = new
LatLng((Double.parseDouble(arrayLatLng[i])),
Double.parseDouble(arrayLatLng[i+1]));
Log.d("LOG_TAG", "Polygon Coordinates" + Cooordinate_Point);
latLngList.add(Cooordinate_Point);
}
then in map ready method()
@Override
public void onMapReady(GoogleMap googleMap) {
myMap = googleMap;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
DrawPolygon(latLngList);
}
private void DrawPolygon(List<LatLng> latLngList) {
/* myMap.addPolygon(new PolygonOptions().strokeColor(Color.GREEN).fillColor(0x7F228B22).add(latLngList));*/
Polygon polygon = myMap.addPolygon(new PolygonOptions()
.clickable(true)
.add(latLngList));
// Store a data object with the polygon, used here to indicate an arbitrary type.
polygon.setTag("alpha");
polygon.setStrokeWidth(3);
polygon.setStrokeColor(Color.GREEN);
polygon.setFillColor(0x7F228B22);
}
回答1:
Use this code for conversion:
String answer = staticPolyCoords;
answer = answer.replace("lat/lng:" , "");
answer = answer.replace(")" , "]");
answer = answer.replace("(" , "[");
try {
JSONArray jsonArray = new JSONArray(answer);
for (int i = 0; i < jsonArray.length(); i++) {
JSONArray latLong = jsonArray.getJSONArray(i);
double lat = latLong.getDouble(0);
double lon = latLong.getDouble(1);
coordinates.add(new LatLng(lat, lon));
}
} catch (JSONException e) {
e.printStackTrace();
}
And then in your drawPolygon method try this for each loop :
PolygonOptions poly = new PolygonOptions();
for (LatLng latLng : coordinates) {
//use the coordinates.
poly.addAll(Collections.singleton(latLng));
}
Polygon polygon = myMap.addPolygon(poly);
//add here your set methods
myMap.moveCamera(CameraUpdateFactory.newLatLng(coordinates.get(3)));
CameraUpdate zoom = CameraUpdateFactory.zoomTo(15);
myMap.animateCamera(zoom);
}
回答2:
If you want to load your map in google map's application then you can go with the below approch:
String geoUri = "http://maps.google.com/maps?q=loc:" + latitude + "," + longitude + " (" + mTitle + ")";
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(geoUri));
context.startActivity(intent);
Or If you want to load it inside your app try with MapActivity where you need to first enable google map API and then your applied coordinates will be displayed on the map
Please check below link this will be useful to integrate this
https://developers.google.com/maps/documentation/android-sdk/start
回答3:
Call this from your button click listener:
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse("https://www.google.com/maps/@?api=1&map_action=map¢er=" + Coordinates));
mCtx.startActivity(i);
Source: Maps URLs
回答4:
If I understand your question correctly, you need to: first show a static map, then, after clicking, show the same static map, but with several polygons on it. As in the case of the quiz, when the first (question) Activity
of the user is asked for the right place of an object, and the second (answer) Activity
displays the correct place of the object.
For this you need:
1) bind the image of static map to geodetic coordinates;
2) implement GoogleMap.addPolygon() method for draw polygone on it.
Both of that task is not trivial in general, so easiest ways is:
1) If you want quick right answer shown in second activity, request and get from Static Map API in yours first Activity
two maps: first - just with map image, and second - same map, but already with polygons. First image you show in that activity, and to second Activity
(which you show after click) you show second image already with polygons. Or request second image in second Activity
if you want to show answer only for clicked maps. In Official Documentation you can find how to get static map image with polygone on it (take a look at the path
parameter):
https://maps.googleapis.com/maps/api/staticmap
?size=400x400¢er=40.653279,-73.959816&zoom=11
&path=fillcolor:0xAA000033%7Ccolor:0xFFFFFF00%7Cenc:}zswFtikbMjJzZ%7CRdPfZ}DxWvBjWpF~IvJnEvBrMvIvUpGtQpFhOQdKpz@bIx{A%7CPfYlvApz@bl@tcAdTpGpVwQtX}i@%7CGen@lCeAda@bjA%60q@v}@rfAbjA%7CEwBpbAd_@he@hDbu@uIzWcWtZoTdImTdIwu@tDaOXw_@fc@st@~VgQ%7C[uPzNtA%60LlEvHiYyLs^nPhCpG}SzCNwHpz@cEvXg@bWdG%60]lL~MdTmEnCwJ[iJhOae@nCm[%60Aq]qE_pAaNiyBuDurAuB}}Ay%60@%7CEKv_@?%7C[qGji@lAhYyH%60@Xiw@tBerAs@q]jHohAYkSmW?aNoaAbR}LnPqNtMtIbRyRuDef@eT_z@mW_Nm%7CB~j@zC~hAyUyJ_U{Z??cPvg@}s@sHsc@_z@cj@kp@YePoNyYyb@_iAyb@gBw^bOokArcA}GwJuzBre@i\tf@sZnd@oElb@hStW{]vv@??kz@~vAcj@zKa%60Atf@uQj_Aee@pU_UrcA
&key=YOUR_API_KEY
Now maps Static API URLs are restricted to 8192 characters in size. So if your polygon has a lot of points you should use encoded polyline format for polygon points. You can encode your polygon with PolyUtil.encode() method of Maps SDK for Android Utility Library.
2) (IMHO better) use MapView/MapFragment
Lite Mode of Maps SDK for Android that can serve a bitmap image of a map, offering limited interactivity to the user. Polylines are supported in this mode and you can save some traffic. In that case you should place MapView' or 'MapFragment
in first activity and MapView/MapFragment
with same settings (size, camera position etc.) in second activity and when user click on map of first activity just draw polygon of the map of the second and show it. The lite mode functionality for shapes matches the full API:
GoogleMap map;
// ... get a map.
// Add a triangle in the Gulf of Guinea
Polygon polygon = map.addPolygon(new PolygonOptions()
.add(new LatLng(0, 0), new LatLng(0, 5), new LatLng(3, 5), new LatLng(0, 0))
.strokeColor(Color.RED)
.fillColor(Color.BLUE));
回答5:
To draw polygons rectangle correctly try this sort function:
fun sortConvexs(coordinates: MutableList<LatLng>): MutableList<LatLng> {
val input = coordinates
// Returns a positive value, if OAB makes a counter clockwise turn,negative for clockwise turn, and zero if the points are collinear.
fun cross(P: LatLng, _A: LatLng, _B: LatLng): Double {
val part1 = (_A.longitude - P.longitude) * (_B.latitude - P.latitude)
val part2 = (_A.latitude - P.latitude) * (_B.longitude - P.longitude)
return part1 - part2
}
// Sort points
var points = input.sortedWith(
Comparator<LatLng> { coordinate0, coordinate1 ->
when {
(coordinate0.longitude == coordinate1.longitude) && (coordinate0.latitude < coordinate1.latitude) -> 1
(coordinate0.longitude < coordinate1.longitude) -> -1
else -> 0
}
}
)
// Build the lower hull
var lower: MutableList<LatLng> = ArrayList<LatLng>()
points.forEach { p ->
while (lower.size >= 2 && cross(lower[lower.size - 2], lower[lower.size - 1], p) <= 0) {
lower.removeAt(lower.size - 1)
}
lower.add(p)
}
// Build upper hull
var upper: MutableList<LatLng> = ArrayList<LatLng>()
points = points.asReversed()
points.forEach { p ->
while (upper.size >= 2 && cross(upper[upper.size - 2], upper[upper.size - 1], p) <= 0) {
upper.removeAt(upper.size - 1)
}
upper.add(p)
}
// Last point of upper list is omitted because it is repeated at the beginning of the lower list.
upper.removeAt(upper.size - 1)
// Concatenation of the lower and upper hulls gives the total points.
return (upper + lower).toMutableList()
}
fun getApproximateCenter(points: MutableList<LatLng>): LatLng {
// Calc bounds first
val boundsBuilder = LatLngBounds.builder()
points.forEach {
boundsBuilder.include(it)
}
val polygonBounds = boundsBuilder.build()
val centerPoint = polygonBounds.center
// Center point is inside the polygon, return it
if (PolyUtil.containsLocation(centerPoint, points, true)) {
return centerPoint
}
// Center point is out of bounds
// Sample points at fixed percentages of the bounding box’s width East and West of the center point.
val maxSearchSteps = 10
var testPos: LatLng = centerPoint
// Calculate NorthWest point so we can work out height of polygon NW->SE
val northWest = LatLng(polygonBounds.northeast.latitude, polygonBounds.southwest.longitude)
// Work out how tall and wide the bounds are and what our search
// increment will be
val boundsHeight = SphericalUtil.computeDistanceBetween(northWest, polygonBounds.southwest)
val heightIncr = boundsHeight / maxSearchSteps
val boundsWidth = SphericalUtil.computeDistanceBetween(northWest, polygonBounds.northeast)
val widthIncr = boundsWidth / maxSearchSteps
// Expand out from Centroid and find a point within polygon at
// 0, 90, 180, 270 degrees
for (n in 1..maxSearchSteps) {
// Test point North of Centroid
testPos = SphericalUtil.computeOffset(
centerPoint,
(heightIncr * n),
0.0
)
if (PolyUtil.containsLocation(testPos, points, true)) {
break
}
// Test point East of Centroid
testPos = SphericalUtil.computeOffset(
centerPoint,
(widthIncr * n),
90.0
)
if (PolyUtil.containsLocation(testPos, points, true)) {
break
}
// Test point South of Centroid
testPos = SphericalUtil.computeOffset(
centerPoint,
(heightIncr * n),
180.0
)
if (PolyUtil.containsLocation(testPos, points, true)) {
break
}
// Test point West of Centroid
testPos = SphericalUtil.computeOffset(
centerPoint,
(widthIncr * n),
270.0
)
if (PolyUtil.containsLocation(testPos, points, true)) {
break
}
}
return testPos
}
This works for me, based in this swift answer
来源:https://stackoverflow.com/questions/61206574/how-to-draw-polygon-using-string-array-of-latlng-in-google-map