简体   繁体   中英

Mapbox SDK: Changing a marker position at runtime

I'm trying to position a point in mapbox that updates its location using a server data every 30 seconds. How do I do this? I'm using version 7.0.1. So far I've managed to show a marker, but I can't change its location during runtime. The marker is accepting data from server, but only when it starts up.

I tried the following code but my emulator crashes when I try to run it:

package com.example.susmi.rubus;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

import com.mapbox.geojson.Feature;
import com.mapbox.geojson.FeatureCollection;
import com.mapbox.geojson.Point;
import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.maps.Style;
import com.mapbox.mapboxsdk.style.layers.PropertyFactory;
import com.mapbox.mapboxsdk.style.layers.SymbolLayer;
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class Main2Activity extends AppCompatActivity {

private MapView mapView;
String lat = "xx", lon = "xy";
MapboxMap map;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Mapbox.getInstance(this, getString(R.string.access_token));
    setContentView(R.layout.activity_main2);
    Bundle bundle = getIntent().getExtras();
    String s = bundle.getString("xyz").toUpperCase();
    String html = "https://rubus.arduinocommunity.org.bd/api/view_data.php?fbclid=IwAR0pyaB4ZDQhrwAJ99vqAdRmSgAgvpBpKwg4RkgIeJDLu6wiNvWqGCJqFbQ";
    //The thread is only for parsing data from the server
    Thread t = new Thread(() -> {
        try {
            int count = 0;
            Document doc = Jsoup.connect(html).get();
            Element body = doc.body();
            Elements paragraphs = body.getElementsByTag("td");
            for (Element para : paragraphs) {
                String s2 = para.text().toUpperCase();
                if (s2.equals(s)) {
                    count++;
                } else if (count != 0)
                    count++;
                if (count == 3) {
                    lat = s2;
                } else if (count == 4) {
                    lon = s2;
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    });
    t.start();
    try {
        t.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    mapView = findViewById(R.id.mapView);
    mapView.onCreate(savedInstanceState);
    mapView.getMapAsync(new OnMapReadyCallback() {
        @Override
        public void onMapReady(@NonNull final MapboxMap mapboxMap) {
            map = mapboxMap;
            mapboxMap.setStyle(Style.LIGHT, new Style.OnStyleLoaded() {
                @Override
                public void onStyleLoaded(@NonNull Style style) {
// Add the marker image to map
                    double s1 = Double.parseDouble(lat), t = Double.parseDouble(lon);
                    style.addImage("marker-icon-id",
                            BitmapFactory.decodeResource(
                                    Main2Activity.this.getResources(), R.drawable.mapbox_marker_icon_default));
                    GeoJsonSource geoJsonSource = new GeoJsonSource("source-id", Feature.fromGeometry(
                            Point.fromLngLat(t, s1)));
                    style.addSource(geoJsonSource);

                    SymbolLayer symbolLayer = new SymbolLayer("layer-id", "source-id");
                    symbolLayer.withProperties(
                            PropertyFactory.iconImage("marker-icon-id")
                    );
                    style.addLayer(symbolLayer);
                    updateMarker(s, html);
                }
            });
        }
    });
}

public void updateMarker(String s, String html) {
    while(true) {
            //The thread is only for parsing data from the server
        Thread t1 = new Thread(() -> {
            try{
                Thread.sleep(3000);
            }catch(InterruptedException e)
            {
                e.printStackTrace();
            }
            try {
                int count = 0;
                Document doc = Jsoup.connect(html).get();
                Element body = doc.body();
                Elements paragraphs = body.getElementsByTag("td");
                for (Element para : paragraphs) {
                    String s2 = para.text().toUpperCase();
                    if (s2.equals(s)) {
                        count++;
                    } else if (count != 0)
                        count++;
                    if (count == 3) {
                        lat = s2;
                    } else if (count == 4) {
                        lon = s2;
                    }
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        });
            t1.start();
            try{
               t1.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        if (map.getStyle() != null) {
            GeoJsonSource g = map.getStyle().getSourceAs("source-id");
            if (g != null) {
                g.setGeoJson(FeatureCollection.fromFeature(
                        Feature.fromGeometry(Point.fromLngLat(88, 24))//Double.parseDouble(lon), Double.parseDouble(lat)))
                ));
            }
        }
    }
}
// Add the mapView's own lifecycle methods to the activity's lifecycle methods
@Override
public void onStart() {
    super.onStart();
    mapView.onStart();
}

@Override
public void onResume() {
    super.onResume();
    mapView.onResume();
}

@Override
public void onPause() {
    super.onPause();
    mapView.onPause();
}

@Override
public void onStop() {
    super.onStop();
    mapView.onStop();
}

@Override
public void onLowMemory() {
    super.onLowMemory();
    mapView.onLowMemory();
}

@Override
protected void onDestroy() {
    super.onDestroy();
    mapView.onDestroy();
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    mapView.onSaveInstanceState(outState);
}
}    

The problem was that because of the while loop in updateMarker(), the onStyleLoaded method was never finishing and so my emulator was staying blank. Thank you to those who have answered.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM