Android Google Map change polyline colors - java

I am drawing polylines on my Google Map. I'm doing it using:
private Map<UUID, PolylineOptions> data;
private void drawFeatures() {
for (Feature feature : features) {
feature.setUuid(UUID.fromString((String) feature.getProperties().get("id")));
PolylineOptions options = new PolylineOptions();
List<Coordinates> coordinates = ((LineString) feature.getGeometry()).getCoordinates();
for (Coordinates coordinate : coordinates) {
// can't use "addAll(...) since 'coordinates' are not instance of 'LatLng'
options.add(new LatLng(coordinate.getLatitude(), coordinate.getLongitude()));
options.color(Color.RED);
}
mMap.addPolyline(options);
data.put(feature.getUuid(), options);
}
}
And then everything is OK. All my polylines are correctly drawed using the good width and color.
However, after that, I'm trying to update the width and the color (without removing and redrawing all the polylines).
I'm trying to do it with:
private void changeColor() {
for (Map.Entry<UUID, PolylineOptions> entry : data.entrySet()) {
entry.getValue().color(Color.CYAN);
}
}
But there is no changes on my map :/ I've read the Google Developers documentation and I don't find anything about that.
How can I update the color of a polyline without having to remove and re-add it ?

PolylineOptions is just a builder for Polylines which are the objects that are drawn into the map.
Thus, changing the PolylineOptions will not affect the Polylines once they are on the map.
Your private Map<UUID, PolylineOptions> data; should be private Map<UUID, Polyline> data; and you need to add elements to the Map like this:
data.put(feature.getUuid(), mMap.addPolyline(options));

may this help you
MarkerOptions markerOptions = new MarkerOptions();
if (!status.equals("ZERO_RESULTS")) {
for (int i = 0; i < result.size(); i++) {
points = new ArrayList<LatLng>();
points.add(driverLatLng);
lineOptions = new PolylineOptions();
List<HashMap<String, String>> path = result.get(i);
for (int j = 0; j < path.size(); j++) {
HashMap<String, String> point = path.get(j);
double lat = Double.parseDouble(point.get("lat"));
double lng = Double.parseDouble(point.get("lng"));
LatLng position = new LatLng(lat, lng);
points.add(position);
}
points.add(storeLatLng);
if (points.contains(storeLongitude)) {
int index = points.indexOf(storeLongitude);
AppLog.Log(TAG, "Index Value in " + index);
int length = points.size();
points.subList(index, length - 1);
AppLog.Log(TAG, "Arraylist Size after SubList Array" + points.size());
}
lineOptions.addAll(points);
lineOptions.width(13);
lineOptions.color(getResources().getColor(R.color.title_background));
lineOptions.geodesic(true);
lineOptions.zIndex(100);
AppLog.Log(TAG, "lineOptions is" + lineOptions.getPoints());
}
mMap.addPolyline(lineOptions);
//DrawArrowHead(mMap, driverLatLng, storeLatLng);
} else {
GlobalMethod.snackBar(true,activity_driver,appContext,"no root found.");
}

Related

Java android google maps change color polyline where I was

This is how I draw a polyline :
List<LatLng> latLngsList = new ArrayList<>();
for (LegsItem leg : response.body().getRoutes().get(0).getLegs()) {
for (StepsItem step : leg.getSteps()) {
List<LatLng> latLngs = PolyUtil.decode(step.getGeometry());
step.setLatLngs(latLngs);
latLngsList.addAll(latLngs);
}
}
Polyline polyline1 = googleMap.addPolyline(new PolylineOptions()
.addAll(latLngsList));
I draw this on color black but when I am on the polyline(In LatLtg), I want to change the color to blue. To detect if I am on the point, I use the below:
mMap.setOnMyLocationChangeListener
and check if the first not done point is near than 2 m :
double dis = currentLocation.distanceTo(location);
But it does not work correctly
You can use the function distanceBetween which Computes the approximate distance in meters between two locations, and optionally the initial and final bearings of the shortest path between them.
public static boolean checkDistance(LatLng oldPosition, LatLng newPosition) {
float[] results = new float[1];
Location.distanceBetween(oldPosition.latitude, oldPosition.longitude,
newPosition.latitude, newPosition.longitude, results);
return results[0] <= 50.0;
}
Here i set minimum distance 50 meter. these will return true if your current location(latlon) is within 50 miters from your polyline latlon.
Define color value in colors.xml
colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="blue">#0000EE</color>
</resources>
and set color like this :-
Polyline line = mMap.addPolyline(new PolylineOptions()
.addAll(list)
.color(R.color.blue));
EDIT
mMap.setOnMyLocationChangeListener(new GoogleMap.OnMyLocationChangeListener() {
#Override
public void onMyLocationChange(Location location) {
for (LatLng nLatLng : latLngsList) {
double latitude = nLatLng.latitude;
double longitude = nLatLng.longitude;
double myLat = location.getLatitude();
double myLong = location.getLongitude();
if (latitude == myLat && longitude == myLong) {
Polyline polyline1 = googleMap.addPolyline(new PolylineOptions()
.add(nLatLng)
.color(R.color.blue));
} /*else {
Polyline polyline1 = googleMap.addPolyline(new PolylineOptions()
.add(nLatLng)
.color(R.color.black));
}*/
}
}
});
See also: update-polyline-according-to-the-user-moving-android-googlemaps

Processing unfolding maps for each marker

I want to add an image for each marker i have on unfolding maps
Already tried to use Buffer but im not sure what i should do now.
My main class
import de.fhpotsdam.unfolding.*;
import de.fhpotsdam.unfolding.geo.*;
import de.fhpotsdam.unfolding.utils.*;
import de.fhpotsdam.unfolding.marker.*;
UnfoldingMap map;
import java.util.Map; // import java hashmaps
// declare country hashmaps
// key // value
HashMap<String, Country> countries = new HashMap<String, Country>();
//PGraphics buffer;
int countryNumber;
Button country;
public void setup() {
size(800, 600, P2D);
smooth();
//buffer = createGraphics(800, 600);
map = new UnfoldingMap(this);
map.setTweening(true);
map.zoomToLevel(3);
MapUtils.createDefaultEventDispatcher(this, map);
String[] lines = loadStrings("test.csv"); //read file and save lines in a string array
countryNumber = lines.length; // how many lines
println(countryNumber);
for (int i=0; i<countryNumber; i++) { //all csv lines
String line = lines[i]; /// get data from line. Ex: "Portugal,10,91"
String[] elements = split(line, ","); //separate line by ','
String name = elements[0]; // get country name
float lat = parseInt(elements[20]); // lat
float lon = parseInt(elements[21]); // lon
PImage flagIcon;
flagIcon = loadImage(elements[22]); //get image flag name
Country P = new Country(name, lat, lon, flagIcon);
Location mapMarker = new Location(lat,lon);
// Create point markers for locations
SimplePointMarker eachMapMarker = new
SimplePointMarker(mapMarker);
// Add markers to the map
map.addMarkers(eachMapMarker);
paises.put(nome, P );
}
}
public void draw() {
background(255);
map.draw(); // draw map
//image(buffer, 200, 50);
for (Map.Entry p : Countries.entrySet() ) { // get countries hashmap
Country country = (Country) p.getValue();
country.drawInfo();
country.drawCoor();
country.drawIcon();
}
}
My Country class
//my country class
class Country {
String name;
float lat;
float lon;
int posX, posY;
PImage flagIcon;
Pais (String n, float la, float lo, PImage ic) {
name = n;
lat = la;
lon = lo;
flagIcon = ic;
}
void drawIcon() {
image(flagIcon,lat,lon,16,16);
}
void drawInfo() {
Location mapLocal = new Location(lat, lon);
ScreenPosition mapPos = map.getScreenPosition(mapLocal);
float scale = map.getZoom();
// if pointer is near a country
boolean onOver = false;
if (dist(mouseX, mouseY, mapPos.x, mapPos.y)<2*scale) {
onOver = true;
}
if (onOver) {
noStroke();
//fill(255,255,255,255);
//rect(mouseX+18, mouseY-20, 120, 50);
fill(0);
text(name + "\nLat: " + lat + "\nLon: " + lon , mouseX+25, mouseY-5);
}
}
void drawCoor() {
//println(coordinates);
fill(0);
text("coordinates: " + mouseX + " " + mouseY, 650,10);
}
}
Image links are stored on my CSV
This is what im getting and as i can see my images arent synced with my lat and lon. Can anyone give me an hand ?
When you draw the country icon on the map, for the input of x and y in the image(PImage image, float x, float y) function inside drawIcon() method, you are supposed to use the marker's position on the map instead of the latitude and longitude properties.
The specific method is called getScreenPosition(UnfoldingMap map) of AbstractMarker. Please refer to the javadoc for the details. http://unfoldingmaps.org/javadoc/de/fhpotsdam/unfolding/marker/AbstractMarker.html#getScreenPosition(de.fhpotsdam.unfolding.UnfoldingMap)
The reason behind it is that (I think) the markers are added to the map with the map.addMarker method, then rendered together with the map.draw() method, where the latitude and longitude are transferred to their screen positions at the backstage.
Because you are trying to add the country icons on top of the country markers after the map.draw() method, you should try to associate the icon's position to the marker's screen position.
public void draw() {
background(200);
map.draw();
for (Marker m: countryMarkers) {
image(countryIcon, (((AbstractMarker) m).getScreenPosition(map).x,
((AbstractMarker) m).getScreenPosition(map).y);
}
}
It would also help the code look more organized and clean if you make a CountryMarker class extends SimplePointMarker class, which is available in the unfolding maps library.

How to Compare one value with all list entries in one step?

For a special slope for linear distances, I need to check wether a new point with given lat/lon has a distance greater than 10 km with respect to all other points, which are stored in a map. I'd like to avoid, that all points inside the map are compared sequentially.
I tried the following code:
private static Map<Long,String> getTop10DSEGs() throws IOException {
Map<Long,String> top10Dsegs = new HashMap<>();
List<String> allDsegs = loadDsegRanking(rFiles);
//the list allDsegs is a csv with the following structure
//dsegID, Latitide, Longitude
//1167317891449551556,51.435550689697266,6.695819854736328
double LatFromList, LonFromList;
double LatFromMap, LonFromMap;
String[] listArray;
String[] mapArray;
Long firstDseg = Long.parseLong(allDsegs.get(0).substring(0, 19));
top10Dsegs.put(firstDseg, allDsegs.get(0).substring(20));
//Iterating through all dsegs
for(String line : allDsegs){
Long nextID = null;
String nextCoordinates = "0.0000,0.0000";
listArray = line.split(",");
LatFromList = Double.valueOf(listArray[1]);
LonFromList = Double.valueOf(listArray[2]);
//checking all coordinates of maped dsegs
for(Map.Entry<Long, String> entry : top10Dsegs.entrySet()){
List<Double> distanceList = new ArrayList<>();
mapArray = entry.getValue().split(",");
LatFromMap = Double.valueOf(mapArray[0]);
LonFromMap = Double.valueOf(mapArray[1]);
//calculating the distance between the next city from the list and the other dsegs from the map
//result of dist is a double and it's metric is Km.
Double dist = Implements.DistanceCalculator.distance(LatFromMap, LonFromMap, LatFromList, LonFromList, "K");
distanceList.add(dist);
for(Double value : distanceList){
if (dist>10){
nextID = Long.parseLong(listArray[0]);
nextCoordinates = listArray[1] + "," + listArray[2];
}
}
}
if(nextID != null && top10Dsegs.size() < 10){
top10Dsegs.put(nextID, nextStartCoordinates);
}
return top10Dsegs;
}
To avoid calculating and comparing distance between all the already stored points and the new one you may use some kind of grid (or matrix) implemented by (Multi)Map or array. Each cell of the grid may have size of sqrt(10km) and contains all the points with relevant coords. It is easy to calculate coordinates of suitable cell for the point by dividing it's coords by sqrt(10).
So when adding every next point it is possible to check distance to only points in 9 cells (own + around). I suppose it will be much less than all points on the map.
Have a look at anyMatch in the Java 8 Stream API
boolean exists = allDsegs.stream().anyMatch(x -> x.equals(firstDseg /* or whetever you compare */));
Okay guys.
Now I solved it by using the Stream-Api and there allMatch()-Method. The problem was, that I've created a Map to save new elements and furthermore the test check = allDsegs.stream().anyMatch(x->dist>10); was the wrong.
The solution is to use a list(top10List) for the new elements and the test need to check if there are elements in the top10List, which are smaller than 10 km.
Here is the code, which (unfortunately) is not beautiful. Im just a beginner since 7 months:
private static List<Top10Dsegs> getTop10DSEGs() throws IOException {
List<File>rFiles = getRFiles();
List<String> allDsegs = loadDsegRanking(rFiles);
List<Top10Dsegs> top10List = new ArrayList<>();
double startLat_allDsegs, startLon_allDsegs;
double startLat_top10List, startLon_top10List;
String[] listArray;
//declaring the starting dseg and its coordinates
String startEntry = allDsegs.get(0);
Top10Dsegs firstEntry = new Top10Dsegs(startEntry);
top10List.add(firstEntry);
System.out.println("Iteration starts here!\n---------------------");
//begin to iterate over all entries (just ranked)
for(String line : allDsegs){
boolean check=true;
Top10Dsegs nextEntry=null;
//structure from allDsegs:
//DSEG,startLat,startLon
//1231231231231231231, 54.123, 8.456
listArray = line.split(",");
startLat_allDsegs = Double.valueOf(listArray[1]);
startLon_allDsegs = Double.valueOf(listArray[2]);
//start to check if line-entry of allDsegs has a distance > 10 km compared to given Dsegs
for(Top10Dsegs entry : top10List){
startLat_top10List = entry.getStartLat();
startLon_top10List = entry.getStartLon();
//the DistanceCalculator calculates the distance between the dseg from allDsegs and the other dseg from top10Dsegs
DistanceCalculator distanceCalculator = new DistanceCalculator();
Double dist = distanceCalculator.distance(startLat_top10List, startLon_top10List, startLat_allDsegs, startLon_allDsegs, "K");
System.out.println("Checked Dseg: " + listArray[0]);
System.out.println("Distance between checked Dseg and " + entry.getSegmentID() + " = " + dist);
//check if there is a dseg from allDsegs distance > 10 km compared to ALL OTHER dsegs
if(top10List.stream().allMatch(x->dist<10)==true){
check = false;
}
System.out.println("Are all distances > 10 ? \t" + check);
}
if(check==true && top10List.size()<10){
nextEntry = new Top10Dsegs(listArray[0]+","+listArray[1]+","+listArray[2]);
top10List.add(nextEntry);
}
System.out.println("Progress: \n"+top10List.size()+" entries inside top 10 list. \n<---------------->\nNext Iteration:");
}
return top10List;
}

Drawing Polygon on Map

I'am trying to draw a polygon with about 260 coordinates on my Map. But I cant figure out why the polygon is not drawn ? There are no null references in the PolygonOptions nor are their wrong data.
protected void drawOverlayPolygon(JSONArray coordinates) {
PolygonOptions rectOptions = new PolygonOptions();
if (coordinates != null) {
int j = 0;
while(!coordinates.isNull(j))
j++;
ArrayList<LatLng> points = new ArrayList<LatLng>(j);
for (int i = 0; i < j; i++) {
try {
JSONArray latlng = coordinates.getJSONArray(i);
// latlng = coordinates.getJSONArray(i);
if (latlng != null) {
LatLng point = new LatLng(Float.parseFloat(latlng
.getString(0)), Float.parseFloat(latlng
.getString(1)));
// rectOptions.add(point);
points.add(point);
Log.i("LatLng Polygon",
Float.parseFloat(latlng.getString(0)) + " / "
+ Float.parseFloat(latlng.getString(1)));
}
} catch (JSONException e) {
e.printStackTrace();
}
// }
}
rectOptions.addAll(points);
rectOptions.strokeColor(Color.RED);
rectOptions.fillColor(Color.BLUE);
Polygon polygon = mapFragment.getMap().addPolygon(rectOptions);
polygon.setVisible(true);
Polygon polygon2 = mapFragment.getMap().addPolygon(
new PolygonOptions()
.add(new LatLng(0, 0), new LatLng(0, 5),
new LatLng(3, 5)).strokeColor(Color.RED)
.fillColor(Color.BLUE));
}
}
For testing I added a simple Polygon (polygon2) and it gets drawn. I am parsing the coordinates from a JSON File. I logged the corrds and they seem to be alright. One thing I noticed is that die JSONArray coordinates contains null references.
Can anybody give me a clue ?
try adding:
rectOptions.visible(true);
before adding the Polygon to the map.
Thx Steffi I tried to add that but did not work. Everyone who runs in this problem check if the order of your Lat Lng Coordinates is correct. Otherwise your polygone is drawn somewhere in the nowhere :)

Add polygon on google ampv2 android

I want to add polygon on map.here i am retrieving lat lng values from arraylist.I am trying to add a polygon from these lat lng values .But the polygon not added on map.please tell me where i made a mistake
my code
polarl=(ArrayList<HashMap<String, String>>)
getIntent().getSerializableExtra("polMyList");
Log.e("POL ARRAY", polarl.toString());
Polygon polygon;
LatLng polLatLng;
if(polarl.size()>0){
for(int k=0;k<polarl.size();k++){
String polLat =polarl.get(k).get("polLat").toString();
String polLng =polarl.get(k).get("polLng").toString();
if ( !polLat.trim().equals("") && !polLng.trim().equals("")){
double HPollat = Double.parseDouble(polLat.trim());
double HPolLong= Double.parseDouble(polLng.trim());
polLatLng=new LatLng(HPollat, HPolLong);
Log.e("POL LAT LANG", ""+polLatLng);
rectOptions = new
PolygonOptions().add(polLatLng).fillColor(Color.BLUE).strokeColor(Color.RED);
Polygon polygon1 = _googleMap.addPolygon(rectOptions);
}
}
}
Try this way
Polygon polygon;
LatLng polLatLng;
PolygonOptions rectOptions=new PolygonOptions();
if(polarl.size()>0){
for(int k=0;k<polarl.size();k++){
String polLat =polarl.get(k).get("polLat").toString();
String polLng =polarl.get(k).get("polLng").toString();
if ( !polLat.trim().equals("") && !polLng.trim().equals("")){
double HPollat = Double.parseDouble(polLat.trim());
double HPolLong= Double.parseDouble(polLng.trim());
polLatLng=new LatLng(HPollat, HPolLong);
Log.e("POL LAT LANG", ""+polLatLng);
rectOptions.add(polLatLng);
}
}
}
Polygon polygon1 = _googleMap.addPolygon(rectOptions.strokeColor(Color.RED).fillColor(Color.BLUE));
For more information go to this SO POST
Try this code,
ArrayList<LatLng> points= new ArrayList<LatLng>();
polarl=(ArrayList<HashMap<String, String>>)getIntent().getSerializableExtra("polMyList");
LatLng polLatLng;
if(polarl.size()>0){
for(int k=0;k<polarl.size();k++){
String polLat =polarl.get(k).get("polLat").toString();
String polLng =polarl.get(k).get("polLng").toString();
if ( !polLat.trim().equals("") && !polLng.trim().equals("")){
double HPollat = Double.parseDouble(polLat.trim());
double HPolLong= Double.parseDouble(polLng.trim());
polLatLng=new LatLng(HPollat, HPolLong);
points.add(polLatLng);
}
}
}
polygonOptions = new PolygonOptions();
polygonOptions.fillColor(Color.TRANSPARENT);
polygonOptions.strokeColor(Color.RED);
polygonOptions.strokeWidth(3);
polylineOptions.color(Color.RED);
polylineOptions.width(3);
polylineOptions.addAll(points);
map.addPolyline(polylineOptions);

Categories

Resources