Geonames, Google Maps, Geocoding, time zones and everything, everything, everything


Users do not want to deal with the features of coordinates, time zones. Some do not even know how these coordinates are expressed, and what time zones are.
How to make the user good?

This article will explain how to work with coordinates and time zones:
Namely,
  1. Installing Google Maps, considered a small functionality with an example.
  2. Search for a time zone with coordinates (Geonames.org).
  3. Search for coordinates and time zone by city name (Geonames.org).
  4. Determining the name of the terrain by coordinates.




So, the
user wants:

  1. It’s not enough to think.
  2. Click a little.


Therefore, we simply must teach the phone:
  1. Find coordinates and time zone by city name.
  2. Find the time zone by coordinates if maps are used.
  3. Find out the current position of the user.
  4. Find out the exact address by coordinates.


For hasty: click on the link to go directly to the application and description of the code with comments.
For others. Let's do it in order.

Introduction


First, what are time zones (time zones). In principle, this is all on Wikipedia.org, but you can see it succinctly here too
A point on the globe can be determined using two coordinates - latitude and longitude. And this is a well-known fact. But there’s a catch with time zones: there can be absolutely any time zone anywhere on the Earth. It all depends on the level of imagination of the manager in a given territory.
For example, for clarity, now in European Russia the true noon, which is supposed to be at 12:00, appears almost 2 hours later. At noon, the true noon — the Sun at its zenith in Moscow — was at 13:38. In some areas of Russia, a shift in the passage of the Sun at its zenith by as much as 3 hours is obtained.
Back to the numbers. World governmentcommunity was taken for the prime meridian - Greenwich. Time zones are calculated relative to it and as follows. A time zone is a shift of local time at some point on the planet relative to the Greenwich meridian. The entire globe is divided into 24 parts along the meridians. That is, the basic meridians of 0 °, 15 °, 30 °, etc., are taken, and time zones ± 7.5 ° are counted from them. Thus, +00: 00 time zone - and it is designated differently: both UTC, and GMT, and GMT + 00: 00 (there is a difference between UTC and GMT, but in practice in most cases this does not apply) - is from 7.5 ° W to 7.5 ° E, GMT + 01: 00 - from 7.5 ° E up to 22.5 ° east etc. But, in addition to this, there are also state borders, as well as some of the states located in the so-called middle zone, where it is economically feasible to make a shift in the summer by +01: 00 (usually). In the southern hemisphere, a summer shift occurs when winter is in the northern hemisphere. Maternity time was also applied in Russia, due to which the clock was shifted an hour forward. On the seas and oceans, a time zone is used, which is calculated by position in the usual way. And in Antarctica, in general, a separate story is how to consider this matter. Due to all these socio-economic and political reasons, time zones on the planet have accumulated several hundred. And if the program also needs to use time (and time zones change in time), then you can get confused with all these shifts. separate story, how to consider this business. Due to all these socio-economic and political reasons, time zones on the planet have accumulated several hundred. And if the program also needs to use time (and time zones change in time), then you can get confused with all these shifts. separate story, how to consider this business. Due to all these socio-economic and political reasons, time zones on the planet have accumulated several hundred. And if the program also needs to use time (and time zones change in time), then you can get confused with all these shifts.

By the way, it happens that a class Calendarin Javagives an error with an hour shift, if you initialize, for example, the current time and time zone, and then set the time before we switched exclusively to daylight saving time, for example, 1988, the calendar will display hours with a shift of 1 hour. This is treated if you constantly reinitialize the calendar when installing new milliseconds. SimpleDateFormatalways produces a similar error, therefore I do not advise using it for old dates.

The Wikipedia

link to the Geonames.org Wikipedia article is a great resource. There you can either download the database or use the native API for this resource. In this article I will use just the API.

To work with Geonames, you need to register a user who will be able to access the API. And also do not forget to activate it . To do this, go to your account and click on the link there: Click here to enable .
Here the documentation
There is even a library for access , but I personally do not use the library, because errors sometimes occur. It’s easier to work directly with the API through an http request.
License . You can use this product for free.

Everyone knows about Google Maps.
You can see general help on using Google Maps here .

There is also a chip like GeoCoder. You can find out the address by coordinates. But time zones, for some reason, are not there.
I will also use Geonames.org to search for time zones by click .

Setting up Google Maps


For beginners, the editing algorithm is brief AndroidManifest.xml, what is where to get it to work Google Maps and determine the position of the phone. If you
are not interested, click here to browse directly to the description of the features of the application .

1.
inside
:



2.
inside
:


To get android: value = "API_KEY" ( link where it is in the code ), you need:
  • here
  • APIs & auth > Credentials > Create new KEY > Android key
  • in the field, write the following SHA-1-KEY; com.example.android.mapexample

Pictures for android: value = "API_KEY"
Figure 1: Open Console

Figure 2: Enter the key

Picture 3: get API_KEY

Features of obtaining SHA-1-KEY
  • it happens either debug or release. Obtained from the certificate file.
  • certificate file for debug - taken from% USERPROFILE% \. android \ debug.keystore. It is attached to the computer and Eclipse.
  • The certificate file for release is my-release-key.keystore, which is used to digitally sign the application. Every developer knows about this. You can get it like this: developer.android.com/tools/publishing/app-signing.html#cert
  • in order to get a debug-key. open the documentation , and there the section Displaying the debug certificate fingerprint and see how to do it
  • to get the release-key, you need to open the documentation , there is a section Displaying the release certificate fingerprint
  • In the current version of api-console, several SHA-1-KEY combinations can be made; com.example.android.mapexample for one output API_KEY. Convenient with one key on multiple computers.


For Google Maps to work, add an Android library to the project. the path is: \extras\google\google_play_services\. You need to add this: File>New>Project>Android>Android Prject from Existing Code>Next
Do not forget to habrtimezoneadd the project google_play_servicesas a library in the settings of the main project . This must be done in the Project>Properties>Android>Library>Add...

Build project you need for Google APIs 4.4.2 section (you can> 4.0). To do this, put a checkmark in front of the corresponding list item in Project>Properties>Android>Project Build Target. If there is no such item there, then you need to install Google APIs through the Android SDK Manager.

A picture that shows where and what to include.


What to download in the Android SDK Manager.



Application code



Below is an example of an application that is posted on Google Play , the source code is on GitHub .
Comments will be given on the features of the application.
QR for application


Screenshot of Eclipse with the project.


So, what the application can do:
1. Determine the current coordinates
2. Work with the map
3. Determine the position of the city and its time zone by its name.

I will not explain all aspects of the application, but only show the main details and features. If you have a code with little things, it’s not difficult to figure out.

Class AMain. First screen


The application starts with the AMainActivity
Class AMain.java. Class code .

public class AMain extends Activity implements OnClickListener

( link )

OnClickListener - for processing clicks. In my opinion, it is better to handle clicks in this way, since memory will be consumed in smaller quantities, if used
 button.setOnClickListener(this);
, but not
button.setOnClickListener(<новый Listener>);
This effect is especially noticeable when a large number of clickable objects are used.
( link for the button and link for the handler )

What is happening here:
The coordinates of the phone in space are searched using the GSM towers, as well as GPS.
Through this window you can open:
1. Map. For markers on this map, the current phone position and position (latitude / longitude), which is recorded in the text fields AGMap
2, will be transmitted . Search for cities via the Internet. ACityListOnline

The search for coordinates was done using the following main objects:

private LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
private LocationListener gpsLocationListener;
private LocationListener networkLocationListener;

( link )
As soon as the coordinates and / or time change, the event will be processed using LocListener implements LocationListener( link ) in

@Override
	public void onLocationChanged(Location location) {}

( link )
Work with the map

Class AGMap. Map screen


In order for the card to be in the application, you need to create the following block in the resources in the file agmap.xml( link ):


, which is the map. ( link )

Class Activity: AGMap.javaThe class code .

What's going on here.
1. The map opens,
2. The coordinates from the previous screen are transferred to it.
3. There are 2 markers - the current coordinates, and a marker in the center of the screen.
4. You can move the map, when you click on the Save button, the coordinates of the map center will be applied, the name of the region will be determined, the time zone will be determined using Geonames.org.

Features of setting up and using the map.

public class AGMap extends FragmentActivity implements OnCameraChangeListener, OnClickListener
( link )
FragmentActivity- since the map is included in this Activity, you need to use this class from the parents.
OnCameraChangeListener- needed to handle map movement

private GoogleMap mMap; //основной объект (карта), 

which is initialized as follows:

mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
( link )

The provisions of objects (pointers on the map) are stored in

LatLng HEREIAM = null; // текущее положение
LatLng pos = null; // текущее положение центра карты
( link )
In order to draw a marker, you need to make an object with marker settings
mo = new markerOptions(... //настроить его текст, цвет, и т.п.
( link )
and apply it to the map:
mar = mMap.addMarker(mo); 

the output will be Marker mar( link )

I noticed that on some devices when the card is initialized, an error occurs in onCreate(), so you have to wrap the error in
try{}catch(NullPointerException e){}
( link )

All map settings are located

GoogleMapOptions options = new GoogleMapOptions();// настройки карты

( link )
Centering a marker on a map:

@Override
public void onCameraChange(CameraPosition cp) {
			// TODO Auto-generated method stub
			  pos = cp.target;
			  mar1.setPosition(pos);
		}

( link )
Initially, functions for processing the result were added to this function

uniqueExec(); //поиск названия положения
uniqueExecTZ(pos); //поиск часового пояса

But in case of a bad connection, everything will slow down. Use is inconvenient.

The search for the position name is as follows:


Geocoder geoCoder = new Geocoder(getBaseContext(), Locale.getDefault());
		try {
			List
addresses = geoCoder.getFromLocation(point.latitude, point.longitude, 1);// тут и будет список адресов } catch (IOException e) { e.printStackTrace(); } return address; }
( link )
In fairness, it’s worth adding that sometimes a “Service not Available” error occurs. In this case, it is better to supplement this function with a check of the form

if (Geocoder.isPresent()){}
else{}

and in elsemake a direct request for URL:

String googleMapUrl = "http://maps.googleapis.com/maps/api/geocode/json?latlng=" + point.latitude + ","
        		+ point.longitude + "&sensor=false&language=" + Locale.getDefault().getLanguage();

In this case, you if-elsewill need to add the condition here .

The output will be a JSON object, which is also parsed into pieces, as is the case with GeoNames. ( See a bit below )
Unfortunately, there is a limit of 2500 requests per day in the case of the free version.

More details here.

When you click on the save button ( link ), the following occurs:
1. Search for the name of the area by coordinates in the center of the screen. Done using ( link ) in function ( link ) 2. time zone search by coordinates in the center of the screen. Done with ( link ) in function ( link)geocodertask extends AsyncTaskuniqueExec();
TimeZoneTask extends AsyncTaskuniqueExecTZ(pos);)

Requests for http for Geocoderand are Time Zonewrapped in AsyncTask( link 1 and link 2 ), because access to the Internet should occur asynchronously, without clogging the main stream.

In fact, the main part of the app and this article are a few queries on Geonames.org. Here is the first one.


String[] urlString = {"http://api.geonames.org/findNearbyJSON?lat=","&lng=", "&radius=50&username=","&style=full&maxRows=1"};
outURL = urlString[0] +  f.format(lat).replace(",", ".") + urlString[1] + f.format(lon).replace(",", ".") + urlString[2] + _.names1[r.nextInt(_.names1.length)] + urlString[3];

( link 1 )
( link 2 )
The query searches for any one object closer than 50 km away. If this object has a time zone, this is the result. If not, or such objects are not found (for example, a location somewhere in the ocean), then the time zone is calculated by the current latitude and longitude with the usual division of the globe into 24 parts ( link ). Perhaps the object is not chosen arbitrarily, but the nearest one is taken, but I did not check it in detail.
The result is displayed in JSON format. Therefore, in parallel, you can draw other information.

Array names1( reference ) from the class_.javastores logins on Geonames.org. You can store one login, but several are better, since there is a limit on the number of requests per hour. In this case, increasing the number of users and choosing them randomly, it will be possible to proportionally increase the number of requests in such an artificial way. The choice of the user through which the connection occurs occurs randomly with r.nextInt () ( what r is ). In the license, I did not find restrictions for such a trick.

I’ll write again. Attention , do not forget to activate the user . To do this, go to your account and click on the link there: Click here to enable .

The method, of course, is not absolutely accurate, but it is working. And usually this method is quite enough. No complaints have yet been received from end users.

Class ACityListOnline. On this screen, cities are searched by name.



Activity ACityListOnline.javaClass code .

Also used by Geonames.org in

CityTask extends AsyncTask
( link to the class )
( here the CityTask class object is launched )
Here the queries are similar AGMap.java, but the search is by name.
Here is the second of those queries that work with GeoNames:


String[] urlString = {"http://api.geonames.org/searchJSON?q=", "&username=","&style=full"};
outURL = urlString[0] +  URLEncoder.encode(str, "UTF-8") + urlString[1] + _.names1[r.nextInt(_.names1.length)] + urlString[2];

( link 1 )
( link 2 )
If the result is found, it is saved in the class object _Info
( link to the class )
( link to the list of class objects that store the search results )
Further, detailed information can be viewed in another Activity by clicking on the element ListView.
The class object now _Info stores latitude, longitude, time zone, and the international name of the region. If you want to pull out other information (it is also available), you can take it from a JSON object yourself. Everything is simple and tedious.

results


On the main functionality is everything.
Once again, a link to Google Play .
QR for application

Before using the code on GitHub, pay attention ATTENTION :
There are no users from Geonames.org in this code.
Namely, you will need to insert user names into the variable

public static final String[] names1 = {"your_account_1","your_account_2"}; 
in the class _.java( link ), and also insert your own API_KEY. in AndroidManifest.xml( link )
How to get these values, I explained above.
To project from GitHub going, you need to add Project>Properties>Java Build Path>Libraries>Add External JARsthis one file Android_SDK_Path\extras\android\support\v4\android-support-v4.jar. Then go in Project>Properties>Java Build Path>Order and Exportand include this file.
If there is interest in such an article, I can tell you next time how it can be done locally without an Internet connection.

Also popular now: