I\'m currently developing an app for Android which uses google map service. Because users will be able to see thousands of markers I would like to load only those which are curr
The answer would depend on where your markers are coming from. Are they stored within the Android device itself or are they coming from a web server? Either way, if you need to represent thousands of locations symultaneously you might need to implement some form of clustering, which can be done on the client or on the server, if markers come from the web.
See, for example this server side clusterer (2 different versions):
http://maps.forum.nu/server_side_clusterer
http://maps.forum.nu/server_side_clusterer/index2.php
or a client side clusterer:
http://gmaps-utility-library.googlecode.com/svn/trunk/markerclusterer/1.0/
Another alternative would be to use custom tiles, (like Google does), but depending on your exact needs it may be overkill.
You could use getMapCenter and just add or subtract the latitude span or longitude span (divided by 2 of course) to find the bounds.
I'm doing something similar to yourself but I'm using a server. The reason I'm doing so is for computational reasons. When the application first starts a HTTP request is sent to a php script which contains a MySQL query. The php script recieves the users current lat / long and gives back in a JSON all points within 1KM of the current location. The application then parses that JSON into a local MySQL database and does stuff with it.
To send the HTTP request and parse the JSON into a database I'm doing the following..
//http post
try{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://URL");
httppost.setEntity(new UrlEncodedFormEntity(parameters));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
//convert response to string
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");
}
is.close();
result=sb.toString();
}catch(Exception e){
new AlertDialog.Builder(this)
.setTitle("Woops!")
.setMessage("Getlocations:It appears the server is not reachable. Check your connectivity and try again.")
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int which) {
//User wants to start activity..
}
})
.show();
Log.e("log_tag", "Error in connection or convert "+e.toString());
}
//parse json data
try{
System.out.println("parsing data");
JSONArray jArray = new JSONArray(result);
if(icount != 0){
try{
SQLiteDatabase db = tweets.getWritableDatabase();
db.delete(TABLE_NAME,null,null);
}finally {
tweets.close();
}
}
//TODO: Change this to num
for(int i=0;i<jArray.length() && q < 1;i++){
System.out.println("ARRAY LENGTH " + jArray.length());
q++;
JSONObject json_data = jArray.getJSONObject(i);
System.out.println("Getting Info");
Double lat = json_data.getDouble("lat");
Double lng = json_data.getDouble("lng");
String link = json_data.getString("link");
String message = json_data.getString("message");
String sname = json_data.getString("sname");
String name = json_data.getString("name");
//Add each entry to SQL database...
System.out.println("Adding table row!");
try{
addloc(name,sname,message,link,lat,lng);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
tweets.close();
}
count();
}
}catch(JSONException e){
new AlertDialog.Builder(this)
.setTitle("Woops!")
.setMessage("Getlocations: It appears something went wrong processing the information.")
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int which) {
//User wants to start activity..
}
})
.show();
Log.e("log_tag", "Error parsing data "+e.toString());
}
For this to work all you need is a short php file which takes the Lat / lng Something like...
<?php
mysql_connect("host","user","pass");
mysql_select_db("database");
$lat = $_REQUEST['currlat'];
$lng = $_REQUEST['currlng'];
$q=mysql_query("QUERY") or die(mysql_error());
if (mysql_num_rows($q) == 0) {
echo "No rows found, nothing to print so am exiting";
exit;
}
if(!q){
echo "NO RESULT";
exit;
}
while($e=mysql_fetch_assoc($q))
$output[]=$e;
print(json_encode($output));
mysql_close();
?>
That'll take in the values and print results in JSON.
//edit: To get the lat / lng in the first place I'm using the GPS.
Hope this helps.
Where are those place-marks coming from? If they are coming from a web service, check if the web service supports spatial queries. If its a basic point in extent (rectangular envelope) you could do something like this:
Note: (xmin, ymin -> xmax, ymax) are the bounds of your rectangle (extent).
def is_point_in_rect(px, py, xmin, ymin, xmax, ymax):
if px >= xmin and px <= xmax:
if py >= ymin and py <= ymax:
return True
else:
return False
This is something very simple. You can even use the Google Maps Data API to store your place-marks and that has a mechanism to execute spatial queries.
If your data is on Google App Engine, then you could use GeoPt based queries or you could roll your own spatial index. Check out http://code.google.com/p/geomodel/