get Direction and get path android studio - json

i am trying to choose form the autocomplete a place and drew a path to it and when i pick a place from the autocomplete the app crashes.
please see the
--------- beginning of crash
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.saoutimohamed.tewsila, PID: 5924
java.lang.IllegalStateException: no included points
at com.google.android.gms.common.internal.Preconditions.checkState(Unknown
Source:8)
at com.google.android.gms.maps.model.LatLngBounds$Builder.build(Unknown
Source:10)
at com.saoutimohamed.tewsila.WelcomeDriver$4.onResponse(WelcomeDriver.java:271)
at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:70)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6938)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
Application terminated.
logcat and tall me what is wrong with my code
and this is the code
private void getDirection() {
String requestApi;
try {
requestApi = "https://maps.googleapis.com/maps/api/directions/json?" +
"mode=driving&" +
"transit_routing_preference=less_driving&" +
"origin=" + Common.mLastLocation.getLatitude() + "," + Common.mLastLocation.getLongitude() + "&" +
"destination=" + lat+","+lng + "&" +
"key=" + getResources().getString(R.string.google_direction_api);
Log.d("SAOUTI", requestApi);
mService.getPath(requestApi)
.enqueue(new Callback<String>() {
#Override
public void onResponse(Call<String> call, Response<String> response) {
try {
JSONObject jsonObject = new JSONObject(response.body().toString());
JSONArray jsonArray = jsonObject.getJSONArray("routes");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject route = jsonArray.getJSONObject(i);
JSONObject poly = route.getJSONObject("overview_polyline");
String polyline = poly.getString("points");
polyLineList = decodePoly(polyline);
}
LatLngBounds.Builder builder = new LatLngBounds.Builder();
for (LatLng latLng : polyLineList)
builder.include(latLng);
LatLngBounds bounds = builder.build();
CameraUpdate mCameraUpdate = CameraUpdateFactory.newLatLngBounds(bounds, 5);
mMap.animateCamera(mCameraUpdate);
polylineOptions = new PolylineOptions();
polylineOptions.color(Color.GRAY);
polylineOptions.width(5);
polylineOptions.startCap(new SquareCap());
polylineOptions.endCap(new SquareCap());
polylineOptions.jointType(JointType.ROUND);
polylineOptions.addAll(polyLineList);
greyPolyline = mMap.addPolyline(polylineOptions);
blackPolylineOptions = new PolylineOptions();
blackPolylineOptions.color(Color.BLACK);
blackPolylineOptions.width(5);
blackPolylineOptions.startCap(new SquareCap());
blackPolylineOptions.endCap(new SquareCap());
blackPolylineOptions.jointType(JointType.ROUND);
blackPolyline = mMap.addPolyline(blackPolylineOptions);
mMap.addMarker(new MarkerOptions()
.position(polyLineList.get(polyLineList.size() - 1))
.title("Pickup Location"));
ValueAnimator polyLineAnimator = ValueAnimator.ofInt(0, 100);
polyLineAnimator.setDuration(2000);
polyLineAnimator.setInterpolator(new LinearInterpolator());
polyLineAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
List<LatLng> points = greyPolyline.getPoints();
int percentValue = (int) valueAnimator.getAnimatedValue();
int size = points.size();
int newPoints = (int) (size * (percentValue / 100.0f));
List<LatLng> p = points.subList(0, newPoints);
blackPolyline.setPoints(p);
}
});
polyLineAnimator.start();
carMarker = mMap.addMarker(new MarkerOptions().position(currentPosition)
.flat(true)
.icon(BitmapDescriptorFactory.fromResource(R.mipmap.tewsila_car)));
handler = new Handler();
} catch (JSONException e) {
e.printStackTrace();
index = -1;
next = 1;
handler.postDelayed(drawPathRunnable, 3000);
}
}
#Override
public void onFailure(Call<String> call, Throwable t) {
Toast.makeText(WelcomeDriver.this, "" + t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
the line that not responding in the logcat is (LatLngBounds bounds = builder.build();)

I had this same issue and i removed
"+getResources().getString(R.string.google_direction_api)" part from the requestApi. Perfectlr worked for me. But i don't know the reason.
requestApi = "https://maps.googleapis.com/maps/api/directions/json?" +
"mode=driving&" +
"transit_routing_preference=less_driving&" +
"origin=" + Common.mLastLocation.getLatitude() + "," + Common.mLastLocation.getLongitude() + "&" +
"destination=" + lat+","+lng + "&" +
"key=";

Related

How to fast bulk insert from json data in sqlite in android

I have written this code to insert json data in to sqlite in android its working fine but i have 50000+ row to insert so its taking so much time to insert into sqlite database. So how can I insert this data in fastest way please kindly give me the code I am very new in android. thank in advance.
Below i have written my code to insert data
private void insertItemDetails() {
final ProgressDialog loading = ProgressDialog .show(this,"Updating Data From Tally","Please wait");
StringRequest stringRequest=new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
loading.show();
itemDatabaseCon.open();
itemDatabaseCon.delete();
itemDatabaseCon.close();
itemDatabaseCon.open();
itemDatabaseCon.createTable();
int a=response.length();
// boolean b=a.equalsIgnoreCase("no");
Log.d("value", String.valueOf(a));
if (a==2) {
Log.d("inside item if loop ",response);
}
else {
JSONObject jsonObject = new JSONObject(response);
JSONArray array = jsonObject.getJSONArray("posts");
for (int i = 0; i < array.length(); i++) {
JSONObject ob = array.getJSONObject(i);
String stockid = ob.getString("stockid");
String itemname = ob.getString("itemname");
String group = ob.getString("group");
String baseunit = ob.getString("baseunit");
String alternateunit = ob.getString("alternateunit");
String gst = ob.getString("gst");
String hsn = ob.getString("hsn");
String mrp = ob.getString("mrp");
String sdtsellrate = ob.getString("sdtsellrate");
String closingstock = ob.getString("closingstock");
ContentValues contentValues = new ContentValues();
contentValues.put(Constant2.key_itemstockid, stockid);
contentValues.put(Constant2.key_itemname, itemname);
contentValues.put(Constant2.key_itemgroup, group);
contentValues.put(Constant2.key_itembaseunit, baseunit);
contentValues.put(Constant2.key_itemalternateunit, alternateunit);
contentValues.put(Constant2.key_itemgst, gst);
contentValues.put(Constant2.key_itemhsn, hsn);
contentValues.put(Constant2.key_itemmrp, mrp);
contentValues.put(Constant2.key_itemsdtsellrate, sdtsellrate);
contentValues.put(Constant2.key_itemclosingstock, closingstock);
itemDatabaseCon.insert(Constant2.Table_name, contentValues);
}
}
loading.dismiss();
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("got api error ffff" , error.getMessage());
}
});
RequestQueue requestQueue= Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
Here is my database controller code.
public class ItemDatabaseCon {
String TAG = "DBAdapter";
private SQLiteDatabase db;
private ItemDatabaseCon.DBHelper dbHelper;
public ItemDatabaseCon (Context context) {
dbHelper = new ItemDatabaseCon.DBHelper(context);
}
public void open() {
if (null == db || !db.isOpen()) {
try {
db = dbHelper.getWritableDatabase();
} catch (SQLiteException sqLiteException) {
}
}
}
public void close() {
if (db != null) {
db.close();
}
}
public int insert(String table, ContentValues values) {
try {
db = dbHelper.getWritableDatabase();
int y = (int) db.insert(table, null, values);
db.close();
Log.e("Data Inserted", "Item Data Inserted");
Log.e("number of row", y + "");
return y;
} catch (Exception ex) {
Log.e("Error Insert", ex.getMessage().toString());
return 0;
}
}
public void delete() {
db.execSQL("DROP TABLE IF EXISTS " + Constant2.Table_name);
}
public int getCount()
{
db = dbHelper.getWritableDatabase();
String qry="SELECT * FROM "+Constant2.Table_name;
Cursor cursor=db.rawQuery(qry,null);
return cursor.getCount();
}
public void createTable()
{
String create_sql = "CREATE TABLE IF NOT EXISTS " + Constant2.Table_name + "("
+ Constant2.key_id + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ Constant2.key_itemstockid + " TEXT ," + Constant2.key_itemname + " TEXT ," + Constant2.key_itemgroup + " TEXT ,"
+ Constant2.key_itembaseunit + " TEXT ,"+ Constant2.key_itemalternateunit + " TEXT ,"+ Constant2.key_itemgst + " TEXT ,"
+ Constant2.key_itemhsn + " TEXT ,"+ Constant2.key_itemmrp + " TEXT ,"+ Constant2.key_itemsdtsellrate + " TEXT ,"
+ Constant2.key_itemclosingstock + " TEXT " + ")";
db.execSQL(create_sql);
}
public Cursor getAllRow(String table) {
return db.query(table, null, null, null, null, null, Constant2.key_id);
}
private class DBHelper extends SQLiteOpenHelper {
public DBHelper(Context context) {
super(context, Constant2.DB_Name, null, Constant2.Db_Version);
}
#Override
public void onCreate(SQLiteDatabase db) {
String create_sql = "CREATE TABLE IF NOT EXISTS " + Constant2.Table_name + "("
+ Constant2.key_id + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ Constant2.key_itemstockid + " TEXT ," + Constant2.key_itemname + " TEXT ," + Constant2.key_itemgroup + " TEXT ,"
+ Constant2.key_itembaseunit + " TEXT ,"+ Constant2.key_itemalternateunit + " TEXT ,"+ Constant2.key_itemgst + " TEXT ,"
+ Constant2.key_itemhsn + " TEXT ,"+ Constant2.key_itemmrp + " TEXT ,"+ Constant2.key_itemsdtsellrate + " TEXT ,"
+ Constant2.key_itemclosingstock + " TEXT " + ")";
db.execSQL(create_sql);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + Constant2.Table_name);
}
}
}
You could do the inserts inside a single SQLite transaction. This would significantly reduce the disk writes from 50000+ to very few.
That is before the loops starts begin a transaction using the SQLiteDatabase's beginTransaction() method.
After the loop has completed (all rows have been inserted) successfully use the setTransactionSuccessful() method followed by the endTransactionMethod()
Note if you do not setTransactionSuccessful then the changes would be rolled back (so if you encounter an issue/error and want the changes (inserts) to not be applied use appropriate logic so that the setTransactionSuccessful is skipped but that the endTransaction is run)
e.g. The following might be suitable:-
....
else {
itemDatabaseCon.beginTransaction(); //<<<<<<<<<< ADDDED start the transaction
JSONObject jsonObject = new JSONObject(response);
JSONArray array = jsonObject.getJSONArray("posts");
for (int i = 0; i < array.length(); i++) {
JSONObject ob = array.getJSONObject(i);
String stockid = ob.getString("stockid");
String itemname = ob.getString("itemname");
String group = ob.getString("group");
String baseunit = ob.getString("baseunit");
String alternateunit = ob.getString("alternateunit");
String gst = ob.getString("gst");
String hsn = ob.getString("hsn");
String mrp = ob.getString("mrp");
String sdtsellrate = ob.getString("sdtsellrate");
String closingstock = ob.getString("closingstock");
ContentValues contentValues = new ContentValues();
contentValues.put(Constant2.key_itemstockid, stockid);
contentValues.put(Constant2.key_itemname, itemname);
contentValues.put(Constant2.key_itemgroup, group);
contentValues.put(Constant2.key_itembaseunit, baseunit);
contentValues.put(Constant2.key_itemalternateunit, alternateunit);
contentValues.put(Constant2.key_itemgst, gst);
contentValues.put(Constant2.key_itemhsn, hsn);
contentValues.put(Constant2.key_itemmrp, mrp);
contentValues.put(Constant2.key_itemsdtsellrate, sdtsellrate);
contentValues.put(Constant2.key_itemclosingstock, closingstock);
itemDatabaseCon.insert(Constant2.Table_name, contentValues);
}
itemDatabaseCon.setTransactionSuccessful(); //<<<<<<<<<< ADDED indicate that changes (inserts) are all good
itemDatabaseCon.endTransaction(); //<<<<<<<<<< ADDED end the transaction
}
loading.dismiss();
....
//<<<<<<<<<< indicates the changed/added code
Edit
However, considering the insert method the above will have no affect as you are closing the database after an insert. Closing the database and then re-opening it is very costly resource wise.
As such to benefit from running all the inserts in a single transaction you could use :-
public int insert(String table, ContentValues values) {
try {
db = dbHelper.getWritableDatabase();
int y = (int) db.insert(table, null, values);
//db.close(); //<<<<<<<<<< Commented out so as to not close the database
Log.e("Data Inserted", "Item Data Inserted");
Log.e("number of row", y + "");
return y;
} catch (Exception ex) {
Log.e("Error Insert", ex.getMessage().toString());
return 0;
}
}

How to get Address from Lat Long

Hello i am creating App for iOS and Android. The issue i want to fix that on the load on page i want to display the map with the address. I can get Lat Long successfully but i cannot getting address that i want to display on a label. Below is my code that i am using.
using Plugin.Geolocator;
using Xamarin.Forms.Maps;
private Position _position;
// Map map;
double Lat, Long;
string address = "";
public TestPage()
{
NavigationPage.SetHasNavigationBar(this, false);
InitializeComponent();
GetPosition();
if (_position != null)
{
Lat = _position.Latitude;
Long = _position.Longitude;
}
//Task<String> str = GetAddress();
map.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(Lat, Long), Distance.FromMiles(1)));
var position = new Position(Lat, Long);
var pin = new Pin
{
Type = PinType.Place,
Position = position,
Label = ""
};
map.Pins.Add(pin);
var zoomLevel = 17.83;
var latlongdegrees = 360 / (Math.Pow(2, zoomLevel));
map.MoveToRegion(new MapSpan(position, latlongdegrees, latlongdegrees));
LabelTime.Text = DateTime.Now.ToString("hh:mm tt") + " " + DateTime.Now.ToString("MM/dd/yyyy");
string recentAddress = address; // trying to get adderss for location
}
GetPosition()
public async void GetPosition()
{
Plugin.Geolocator.Abstractions.Position position = null;
try
{
var locator = CrossGeolocator.Current;
locator.DesiredAccuracy = 100.0;
position = await locator.GetLastKnownLocationAsync();
if (position != null)
{
_position = new Position(position.Latitude, position.Longitude);
//got a cahched position, so let's use it.
return;
}
if (!locator.IsGeolocationAvailable || !locator.IsGeolocationEnabled)
{
//not available or enabled
return;
}
position = await locator.GetPositionAsync(TimeSpan.FromSeconds(10), null, true);
}
catch (Exception ex)
{
// error(ex.Message, Convert.ToString(ex.InnerException), ex.Source, ex.StackTrace);
}
_position = new Position(position.Latitude, position.Longitude);
if (position == null)
return;
}
GetAddress()
public async Task<String> GetAddress()
{
// string Addrsss = "";
try
{
Geocoder geoCoder = new Geocoder();
if (_position != null)
{
var possibleAddresses = await geoCoder.GetAddressesForPositionAsync(_position);
await Task.Delay(2000);
foreach (var a in possibleAddresses)
{
address += a + "\n";
}
}
return address;
}
catch (Exception ex)
{
throw;
}
}
I also try to get the current address on OnAppearing()
protected override void OnAppearing()
{
this.Appearing += TestPage_Appearing; //Subscribe to event
base.OnAppearing();
}
protected async void TestPage_Appearing(object sender, EventArgs args)
{
GetPosition();
address= await GetAddress();
string a = address;
this.Appearing -= TestPage_Appearing; //Unsubscribe
}
You can get placemark address using Xamarin.Essentials as below,
protected async override void OnAppearing()
{
await GetAddress();
}
private async Task GetAddress()
{
var lat = 47.673988;
var lon = -122.121513;
var placemarks = await Geocoding.GetPlacemarksAsync(lat, lon);
var placemark = placemarks?.FirstOrDefault();
if (placemark != null)
{
var geocodeAddress =
$"AdminArea: {placemark.AdminArea}\n" +
$"CountryCode: {placemark.CountryCode}\n" +
$"CountryName: {placemark.CountryName}\n" +
$"FeatureName: {placemark.FeatureName}\n" +
$"Locality: {placemark.Locality}\n" +
$"PostalCode: {placemark.PostalCode}\n" +
$"SubAdminArea: {placemark.SubAdminArea}\n" +
$"SubLocality: {placemark.SubLocality}\n" +
$"SubThoroughfare: {placemark.SubThoroughfare}\n" +
$"Thoroughfare: {placemark.Thoroughfare}\n";
Console.WriteLine(geocodeAddress);
}
}
refer this link for in depth details
Also this one for detailed implementation

Read arbitrarily json data to a javafx treeview,and only show the first element of any array in it

I need to show a json file on a javafx treeview,the structure of the json is unknown.Like the web site: json viewer site
I show the tree for user to select path of a value(like xpath of xml),so if the json is too big,I only need to show the first element of any array in json.
for example,the original data is:
{
name:"tom",
schools:[
{
name:"school1",
tags:["maths","english"]
},
{
name:"school2",
tags:["english","biological"]
},
]
}
I want to show:
again:the structure of json is unknown,it is just one example.
There's no other option than recursively handling the json and create the TreeItem structure based on the element info.
(There's probably a better way of adding the symbols, but I didn't find appropriate icons.)
private static final String INPUT = "{\n"
+ " name:\"tom\",\n"
+ " schools:[\n"
+ " {\n"
+ " name:\"school1\",\n"
+ " tags:[\"maths\",\"english\"]\n"
+ " },\n"
+ " {\n"
+ " name:\"school2\",\n"
+ " tags:[\"english\",\"biological\"]\n"
+ " },\n"
+ " ]\n"
+ "}";
private static final Image JSON_IMAGE = new Image("https://i.stack.imgur.com/1slrh.png");
private static void prependString(TreeItem<Value> item, String string) {
String val = item.getValue().text;
item.getValue().text = (val == null
? string
: string + " : " + val);
}
private enum Type {
OBJECT(new Rectangle2D(45, 52, 16, 18)),
ARRAY(new Rectangle2D(61, 88, 16, 18)),
PROPERTY(new Rectangle2D(31, 13, 16, 18));
private final Rectangle2D viewport;
private Type(Rectangle2D viewport) {
this.viewport = viewport;
}
}
private static final class Value {
private String text;
private final Type type;
public Value(Type type) {
this.type = type;
}
public Value(String text, Type type) {
this.text = text;
this.type = type;
}
}
private static TreeItem<Value> createTree(JsonElement element) {
if (element.isJsonNull()) {
return new TreeItem<>(new Value("null", Type.PROPERTY));
} else if (element.isJsonPrimitive()) {
JsonPrimitive primitive = element.getAsJsonPrimitive();
return new TreeItem<>(new Value(primitive.isString()
? '"' + primitive.getAsString() + '"'
: primitive.getAsString(), Type.PROPERTY));
} else if (element.isJsonArray()) {
JsonArray array = element.getAsJsonArray();
TreeItem<Value> item = new TreeItem<>(new Value(Type.ARRAY));
// for (int i = 0, max = Math.min(1, array.size()); i < max; i++) {
for (int i = 0, max = array.size(); i < max; i++) {
TreeItem<Value> child = createTree(array.get(i));
prependString(child, Integer.toString(i));
item.getChildren().add(child);
}
return item;
} else {
JsonObject object = element.getAsJsonObject();
TreeItem<Value> item = new TreeItem<>(new Value(Type.OBJECT));
for (Map.Entry<String, JsonElement> property : object.entrySet()) {
TreeItem<Value> child = createTree(property.getValue());
prependString(child, property.getKey());
item.getChildren().add(child);
}
return item;
}
}
#Override
public void start(Stage primaryStage) {
JsonParser parser = new JsonParser();
JsonElement root = parser.parse(INPUT);
TreeItem<Value> treeRoot = createTree(root);
TreeView<Value> treeView = new TreeView<>(treeRoot);
treeView.setCellFactory(tv -> new TreeCell<Value>() {
private final ImageView imageView;
{
imageView = new ImageView(JSON_IMAGE);
imageView.setFitHeight(18);
imageView.setFitWidth(16);
imageView.setPreserveRatio(true);
setGraphic(imageView);
}
#Override
protected void updateItem(Value item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setText("");
imageView.setVisible(false);
} else {
setText(item.text);
imageView.setVisible(true);
imageView.setViewport(item.type.viewport);
}
}
});
final Scene scene = new Scene(treeView);
primaryStage.setScene(scene);
primaryStage.show();
}

ReverseGeocodeQuery giving error

ReverseGeocodeQuery is giving error
1.in "GeoCoordinate(47.60887, -122.34094); " method must have a return type
2.in "reverseGeocode.GeoCoordinate line " reverseGeocode is a field but its used like a type..
ReverseGeocodeQuery reverseGeocode = new ReverseGeocodeQuery();
reverseGeocode.GeoCoordinate = new GeoCoordinate(47.60887, -122.34094);
reverseGeocode.QueryCompleted += reverseGeocode_QueryCompleted;
reverseGeocode.QueryAsync();
void reverseGeocode_QueryCompleted(objectsender,QueryCompletedEventArgs<IList<MapLocation>> e)
{
MapAddress geoAddress = e.Result[0].Information.Address;
}
i used namespace-- using Microsoft.Phone.Maps.Services;
how to rectify this errors..
GOT THE ANSWER
GeoCoordinateWatcher myLocationWatcher;
private GeoCoordinate MyCoordinate = null;
private async void GetCurrentCoordinate()
{
Geolocator geolocator = new Geolocator();
geolocator.DesiredAccuracy = PositionAccuracy.High;
try
{
Geoposition currentPosition = await geolocator.GetGeopositionAsync(TimeSpan.FromMinutes(1), TimeSpan.FromSeconds(10));
_accuracy = currentPosition.Coordinate.Accuracy;
MyCoordinate = new GeoCoordinate(currentPosition.Coordinate.Latitude, currentPosition.Coordinate.Longitude);
if (MyReverseGeocodeQuery == null || !MyReverseGeocodeQuery.IsBusy)
{
MyReverseGeocodeQuery = new ReverseGeocodeQuery();
MyReverseGeocodeQuery.GeoCoordinate = new GeoCoordinate(MyCoordinate.Latitude, MyCoordinate.Longitude);
LongitudeTextBlock.Text = MyCoordinate.Longitude.ToString();
LatitudeTextBlock.Text = MyCoordinate.Latitude.ToString();
MyReverseGeocodeQuery.QueryCompleted += ReverseGeocodeQuery_QueryCompleted;
MyReverseGeocodeQuery.QueryAsync();
}
}
catch (Exception ex)
{
// ...
}
}
public void ReverseGeocodeQuery_QueryCompleted(object sender, QueryCompletedEventArgs<IList<MapLocation>> e)
{
if (e.Error == null)
{
if (e.Result.Count > 0)
{
MapAddress address = e.Result[0].Information.Address;
labelResults.Text = "Current Location: " + address.City + ", " + address.State;
}
}
}
public void Button_Click(object sender, RoutedEventArgs e)
{
GetCurrentCoordinate();
}

Drawing a route between 2 locations Google Maps API Android V2

I was playing around with the Google Maps API V2 on android.
Trying to get a path between 2 locations and doing this with the JSON Parsing.
I am getting a route. and the route starts out how it should be. but then at one point it goes the wrong way.
My end destination ends up wrong. And with some other locations my app just gets terminated.
This is what i have done
Here is my makeURL method
public String makeUrl(){
StringBuilder urlString = new StringBuilder();
urlString.append("http://maps.googleapis.com/maps/api/directions/json");
urlString.append("?origin="); //start positie
urlString.append(Double.toString(source.latitude));
urlString.append(",");
urlString.append(Double.toString(source.longitude));
urlString.append("&destination="); //eind positie
urlString.append(Double.toString(dest.latitude));
urlString.append(",");
urlString.append(Double.toString(dest.longitude));
urlString.append("&sensor=false&mode=driving");
return urlString.toString();
}
my JSON parser
public class JSONParser {
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
public JSONParser() {
// TODO Auto-generated constructor stub
}
public String getJSONFromURL(String url){
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
} catch(UnsupportedEncodingException e){
e.printStackTrace();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while((line = reader.readLine()) != null){
sb.append(line + "\n");
//Log.e("test: ", sb.toString());
}
json = sb.toString();
is.close();
} catch (Exception e) {
// TODO Auto-generated catch block
Log.e("buffer error", "Error converting result " + e.toString());
}
return json;
}
I draw my Path with this method
public void drawPath(String result){
try{
final JSONObject json = new JSONObject(result);
JSONArray routeArray = json.getJSONArray("routes");
JSONObject routes = routeArray.getJSONObject(0);
JSONObject overviewPolylines = routes.getJSONObject("overview_polyline");
String encodedString = overviewPolylines.getString("points");
Log.d("test: ", encodedString);
List<LatLng> list = decodePoly(encodedString);
LatLng last = null;
for (int i = 0; i < list.size()-1; i++) {
LatLng src = list.get(i);
LatLng dest = list.get(i+1);
last = dest;
Log.d("Last latLng:", last.latitude + ", " + last.longitude );
Polyline line = googleMap.addPolyline(new PolylineOptions().add(
new LatLng(src.latitude, src.longitude), new LatLng(dest.latitude, dest.longitude))
.width(2)
.color(Color.BLUE));
}
Log.d("Last latLng:", last.latitude + ", " + last.longitude );
}catch (JSONException e){
e.printStackTrace();
}
}
And I decode my JSON with
private List<LatLng> decodePoly(String encoded){
List<LatLng> poly = new ArrayList<LatLng>();
int index = 0;
int length = encoded.length();
int latitude = 0;
int longitude = 0;
while(index < length){
int b;
int shift = 0;
int result = 0;
do {
b = encoded.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int destLat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
latitude += destLat;
shift = 0;
result = 0;
do {
b = encoded.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b > 0x20);
int destLong = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
longitude += destLong;
poly.add(new LatLng((latitude / 1E5),(longitude / 1E5) ));
}
return poly;
}
And then coded with an AsyncTask
Thanks in advance.
Sorry for the long wait.. i have fixed it a while ago but i hadn't put my solution on here yet.
It was basically a typo...
In my Json decoder i use 2 Do while statements with
while (b >= 0x20);
In the second Do While statement i forgot the "=".
Therefore it wasn't rendering correctly...
thanks
I believe that you are creating your LatLng objects from overview_polyline. This, according to Google documentation "contains an object holding an array of encoded points that represent an approximate (smoothed) path of the resulting directions.".
I'm pretty sure that you can get a more detailed route building your LatLng object based on legs[] and steps[] data as the official documentation states that A step is the most atomic unit of a direction's route, containing a single step describing a specific, single instruction on the journey.
Take a look at:
https://developers.google.com/maps/documentation/directions/#Routes
Tmichel,
the Michael has the correctly wave, because on legs and steps on your route plot the line out of the street.
Legs and steps, has informations around coordinates for informations to alert the user.
Polylines are the correct and precise points over the street.
Sorry my bad english