I have got 3 maps on my app, want to change longtitude and latitude with Parse.com if it's needed.
I follow this way:
String place1latitudeSTRING = "49.986595";
public Double place1latitude = Double.valueOf(place1latitudeSTRING);
String place1longitudeSTRING = "31.294509";
public Double place1longitude = Double.valueOf(place1longitudeSTRING);
then i download changes from Parse.com. In my LOG i can see that application really download new double.
Then i have got condition:
Double list_maps_new_coordinates = maps_coordinates.get(6);
String place1longitudeChanged = Double.toString(list_maps_new_coordinates);
place1longitude = Double.valueOf(place1longitudeChanged);
And finally in my private void SetUpMap i have got this code:
mMap.addMarker(new MarkerOptions().position(new LatLng(place1latitude, place1longitude))
Question: Why not change the coordinates? Where is mistake?
Related
I am very new to Java programming, I would appreciate any kind of help.
So I want to display a set of lat-long coordinates (more than 50 coordinates) in Java-based canvas (e.g JFrame, Processing) from a WFS server. I have managed to parse lat-long value and print it to the console. Now I'm stuck in how to bring the lat-long coordinates to the screen coordinates (I'd like to draw it on 1000x500 size). I've tried to search for the reference but couldn't find the simplest one for a beginner like me. Here is the current part of my code :
String[] splitc = coord.split(",");
String lon = splitc[0];
String lat = splitc[1];
//parse string to float
float loncoord=Float.parseFloat(lon);
float latcoord=Float.parseFloat(lat);
Can I transfer the coordinates from the WFS to screen coordinates using world2screen.translate of Geotools library as in https://docs.geotools.org/latest/userguide/library/referencing/axis.html ?
In processing, there is a map() function (https://processing.org/reference/map_.html) to transfer from a range to another. I've tried it but it didn't work on my IDE.
One super noob question, I'm trying to store the WFS connection in a function so I can call it in another class, should I store it in static void or use "return"?
If someone can provide an example of a similar task, that would be very helpful. Thanks (Sara)
You can use this formula instead:
float x = ((WIDTH/360.0) * (180 + loncoord));
float y = ((HEIGHT/180.0) * (90 - latcoord));
It should work... Note that it returns a float and takes 5 arguments of the form:
map(input, inputMin, inputMax, outputMin, outputMax)
You only want to create the connection once, so you're left with two viable options: defining the connection as a static variable of a static class, or defining the connection as an instance variable of a class following the singleton pattern.
Assuming you chose the former approach, the method that returns the connection variable should therefore be static but not void:
public static connectionType getConnection() {
return connectionObject;
}
... where connectionType is the datatype of the connection.
The easiest way is to create a GeoTools WFSDataStore, this code builds up the getCapabilities string if the user has given just a URL to the service endpoint and handles authentication if needed. The datastore is stored in a field of the class:
public FetchWFS(String url, String user, String passwd) throws IOException, URISyntaxException {
if (!user.isEmpty()) {
auth = true;
}
baseURL = new URL(url);
List<NameValuePair> nvp = URLEncodedUtils.parse(baseURL.toURI(), "UTF-8");
NameValuePair service = new BasicNameValuePair("service", "wfs");
NameValuePair request = new BasicNameValuePair("request", "getCapabilities");
NameValuePair version = new BasicNameValuePair("version", "2.0.0");
HashMap<String, NameValuePair> parts = new HashMap<>();
parts.put(service.getName(), service);
parts.put(request.getName(), request);
parts.put(version.getName(), version);
for (NameValuePair part : nvp) {
if (part.getName().equalsIgnoreCase("SERVICE")) {
// We don't care what they think this should be
} else if (part.getName().equalsIgnoreCase("REQUEST")) {
// This must be getCapabuilities so we ignore them
} else if (part.getName().equalsIgnoreCase("VERSION")) {
System.out.println("Changing version to " + part.getValue());
parts.put(version.getName(), part);
} else {
parts.put(part.getName(), part);
}
}
URIBuilder builder = new URIBuilder();
builder.setScheme(baseURL.getProtocol());
builder.setHost(baseURL.getHost());
builder.setPort(baseURL.getPort());
builder.setPath(baseURL.getPath());
List<NameValuePair> p = new ArrayList<>();
p.addAll(parts.values());
builder.setParameters(p);
// builder.addParameter("viewparams", "q:\"mySolrQuery\"");
URI uri = builder.build();
System.out.println(uri);
baseURL = uri.toURL();
// fetch the DataStore
Map<String, Object> params = new HashMap<>();
params.put(WFSDataStoreFactory.URL.key, baseURL);
// params.put(WFSDataStoreFactory.WFS_STRATEGY.key, "mapserver");
if (auth) {
params.put(WFSDataStoreFactory.USERNAME.key, user);
params.put(WFSDataStoreFactory.PASSWORD.key, passwd);
}
// params.put(WFSDataStoreFactory.WFS_STRATEGY.key, "mapserver");
datastore = DataStoreFinder.getDataStore(params);
}
Once you have a DataStore (of any type) you can get a list of available
featureTypes and then add one (or more) of them to a map:
JMapFrame frame = new JMapFrame();
MapContent map = new MapContent();
String[] names = datastore.getNames();
featureSource = store.getFeatureSource(names[0]); //fetch first featureType
schema = featureSource.getSchema();
Style style = SLD.createSimpleStyle(schema);
this.layer = new FeatureLayer(featureSource, style);
map.addLayer(layer);
frame.enableToolBar(true);
frame.setMinimumSize(new Dimension(800, 400));
frame.setVisible(true);
The GeoTools Quickstart Tutorial will help you get started with simple mapping, and the Map Styling tutorial will allow you to generate a prettier map when you want more than a simple black and white default map.
I am trying to query the nearest documenst to the user location using geofirestore, my code fetch 1 document only, and as you see in the code I set the radius to 100km, and I set the location of the document from the same location.
This is the document I am querying it
And this is the other document with the same radius
I tried to print the snapshot result in a map and it's only print 1 document
here I send the document id to build the query into recyclerView
Map<String,Object> stringIntegerMap=new HashMap<>();
private void getNearestEstate(){
GeoQuery geoQuery = geoFirestore.queryAtLocation(new GeoPoint(latitude, longitude), 100);
geoQuery.addGeoQueryDataEventListener(new GeoQueryDataEventListener() {
#Override
public void onDocumentEntered(DocumentSnapshot documentSnapshot, GeoPoint geoPoint) {
stringIntegerMap=documentSnapshot.getData();
Query query=propertyRef.whereEqualTo("mID",Integer.parseInt(documentSnapshot.getId()));
dataFetch(query,R.id.discoverRV);
//here how i tried to print the result to see how many documents i got
for (Map.Entry<String,Object> entry : stringIntegerMap.entrySet()) {
String key = entry.getKey();
String value = entry.getValue().toString();
Toast.makeText(mContext,key+" "+value,Toast.LENGTH_LONG).show();
}
}
And here i build the query and send it to recyclerview adapter
private void dataFetch(Query query,int rvView){
FirestoreRecyclerOptions<Property> options = new FirestoreRecyclerOptions.Builder<Property>()
.setQuery(query, Property.class)
.build();
mAdapter = new DiscoverAdapter(options);
RecyclerView recyclerView = root.findViewById(rvView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext(),LinearLayoutManager.HORIZONTAL,false));
recyclerView.setAdapter(mAdapter);
mAdapter.startListening();
}
here the result of the query
I think you are using com.github.imperiumlabs:GeoFirestore-Android, right?
As of version v1.5.0, there is a discrepancy between the code and the documentation. The documentation states that queryAtLocation uses kilometers:
// creates a new query around [37.7832, -122.4056] with a radius of 0.6 kilometers
val geoQuery = geoFirestore.queryAtLocation(GeoPoint(37.7832, -122.4056), 0.6)
However, the code converts from meters to latitude:
fun distanceToLatitudeDegrees(distance: Double) = distance / Constants.METERS_PER_DEGREE_LATITUDE
There is an open issue on Github.
Passing meters to the queryAtLocation should solve the problem.
I'm using google maps to plot markers on a map. I can save the data for ALL these points (it's over 17000 rows with 3 columns: shopId,shopName,lat,long).
I can also send JSON queries specifying my lat/long and the radius at what shops around I want data about. Then I'll receive the data back. This works, but when I create the markers (with AsyncTask) freezing occurs in the app (and it is noticeable).
This is the code I'm using to generate the custom markers on Google maps:
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
try {
JSONArray jsonArray = new JSONArray(result);
String finalReturn[] = result.split("\\r?\\n");
if(jsonArray.get(0).toString().equals("4")) {
for (int i = 1; i < finalReturn.length; i++) {
jsonArray = new JSONArray(finalReturn[i]);
IconGenerator iconGenerator = new IconGenerator(getApplicationContext());
iconGenerator.setStyle(IconGenerator.STYLE_RED);
iconGenerator.setRotation(90);
iconGenerator.setContentRotation(-90);
Bitmap iconBitmap = iconGenerator.makeIcon(jsonArray.get(5).toString());
Marker marker = mMap.addMarker(new MarkerOptions()
.position(new LatLng(jsonArray.getDouble(6), jsonArray.getDouble(7)))
.icon(BitmapDescriptorFactory.fromBitmap(iconBitmap)));
marker.setTitle(jsonArray.getString(1));
marker.setSnippet(jsonArray.getString(2) + " " + jsonArray.getString(8));
}
}
} catch (JSONException e) {
}
My question is, what is the best solution here, store the points in a MySQL server and generate nearest shops from that area (SQlite Getting nearest locations (with latitude and longitude) something like this), or always query the server for the data. Or maybe a hybrid of both (query the server, then save the data in an SQLite db.)
I'm only a beginner in Android so sorry if this question is simple.
The fastest way should be to save the data in an SQLite db and query it from there, but if you only need the few shops that are near the user, it should be fine to simply call the web service every time.
Other than that, the freezing that occurs in your app is most likely due to the onPostExecute Method being called in the UI-Thread and you doing heavy work in this method.
You should not parse your JSON there, but rather in the doInBackground method and for each parsed element call publishProgress that calls the onProgressUpdate Method (which is also executed in the UI-Thread.
Like this, you can handle setting one single marker on the map at a time and that way, the time between the single onProgressUpdate calls can be used by the system to update the UI and so the freezing should no longer occur.
It should look somewhat like this:
protected Void doInBackground(...) {
String result = getResult();
try {
JSONArray jsonArray = new JSONArray(result);
String finalReturn[] = result.split("\\r?\\n");
if(jsonArray.get(0).toString().equals("4")) {
for (int i = 1; i < finalReturn.length; i++) {
jsonArray = new JSONArray(finalReturn[i]);
publishProgress(jsonArray);
}
}
} catch (JSONException e) {
//handle error
}
}
#Override
protected void onProgressUpdate(JSONArray... progress) {
JSONArray array = progress[0];
IconGenerator iconGenerator = new IconGenerator(getApplicationContext());
iconGenerator.setStyle(IconGenerator.STYLE_RED);
iconGenerator.setRotation(90);
iconGenerator.setContentRotation(-90);
Bitmap iconBitmap = iconGenerator.makeIcon(jsonArray.get(5).toString());
Marker marker = mMap.addMarker(new MarkerOptions()
.position(new LatLng(jsonArray.getDouble(6), jsonArray.getDouble(7)))
.icon(BitmapDescriptorFactory.fromBitmap(iconBitmap)));
marker.setTitle(jsonArray.getString(1));
marker.setSnippet(jsonArray.getString(2) + " " + jsonArray.getString(8));
}
I'm trying to figure out the city of where the user is using their location. Using LocationManager and Geocoder I get some nice data from the longitude and latitude, but I can't get one thing. The subAdminArea a.k.a. the city. It always returns null for me, even though everything else including the postal code is received. Is there something I am missing?
Basically this is a method I call for getting data.
public String getLocation(Locale locale, Context context, boolean city, boolean postal, boolean state_prov) throws IOException{
LocationManager locMan = (LocationManager)this.getSystemService(Context.LOCATION_SERVICE);
LocationListener locList = new MyLocList();
Geocoder gC = new Geocoder(context,locale);
Location gpsLocation = locMan.getLastKnownLocation(locMan.GPS_PROVIDER);
locMan.requestLocationUpdates(locMan.NETWORK_PROVIDER, 500, 200, locList);
Location networkLocation = locMan.getLastKnownLocation(locMan.NETWORK_PROVIDER);
if (city)
return (gC.getFromLocation(networkLocation.getLatitude(), networkLocation.getLongitude(), 1).get(0).getSubAdminArea());
else if (postal)
return (gC.getFromLocation(networkLocation.getLatitude(), networkLocation.getLongitude(), 1).get(0).getPostalCode());
else if (state_prov)
return (gC.getFromLocation(networkLocation.getLatitude(), networkLocation.getLongitude(), 1).get(0).getAdminArea());
else
return "";
}
and the call to this method is done via:
String city = getLocation(Locale.getDefault(),getBaseContext(),true,false,false);
The only other option I have found through some research is sending a request to
http://maps.googleapis.com/maps/api/geocode/json?address=POSTALCODE&sensor=true
and it gives me a JSON of that location based on the postal code, which I can then parse, but it seems like a lot of work to find the city.
Could there be something I am missing? Or something I did wrong? I am new to location services for android.
Try this:
Geocoder gc = new Geocoder(context, Locale.getDefault());
List<Address> addresses = gc.getFromLocation(latitude, longitude, maxResults);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < addresses.getMaxAddressLineIndex(); i++)
Log.d("=Adress=",addresses.getAddressLine(i));
}
You will get postal code, city , country, ....
I used this answer and it worked perfectly fine. It was able to get the location despite the problems I initially had in this question.
I am trying to use geocoding to take an address, work out the longitude and latitude and then display an overlay on the map.
I am using the below code, however the log entry Log.e("Found",""+lat); never triggers and I'm not sure why. Can anybody help ?
Thanks !
private void showpins() throws IOException {
Geocoder gc = new Geocoder(this);
String Address = "Oxford Street, London";
Log.e("Lat",""+Address);
List<Address> foundAdresses = gc.getFromLocationName(Address, 5); //Search addresses
int lat;
int lon;
for (int i = 0; i < foundAdresses.size(); ++i) {
Address x = foundAdresses.get(i);
lat = (int) x.getLatitude();
lon = (int) x.getLongitude();
Log.e("Found",""+lat);
List<Overlay> mapOverlays = mapView.getOverlays();
Drawable drawable = this.getResources().getDrawable(R.drawable.pushpin);
CustomizedItemOverlay itemizedOverlay =
new CustomizedItemOverlay(drawable, this);
GeoPoint point = new GeoPoint(lat, lon);
OverlayItem overlayitem =
new OverlayItem(point, "Hello", "Location");
itemizedOverlay.addOverlay(overlayitem);
mapOverlays.add(itemizedOverlay);
}
}
There are definite issues with this in certain emulator API levels. See Issue 8816: service not available. For example API level 8 won't work. I find that API level 7 is OK if you call the method twice. The behaviour on real devices is not known to me. I don't think Google guarantee that the service will always be available.
Either you address is not in Google maps address database or your app does not have internet access privileges.
Check in http://maps.google.com that the address is actually found.
That yor app has internet access privileges. You must have this in ypur app manifest:
<uses-permission android:name="android.permission.INTERNET" />