如何为Android google-maps中的当前位置动态加载标记?

时间:2010-08-05 09:04:00

标签: java android google-maps

我目前正在开发一款使用谷歌地图服务的Android应用。因为用户将能够看到数千个标记,我只想加载当前在地图范围内的那些(即当用户查看特定的地图图块时)。我知道如何使用javascript / html。但是,Android似乎没有提供任何类似的方法,如containsLatLng(latlng)或getBounds(我只发现了getLatitudeSpan和getLongitudeSpan,但我不知道如何使用它们才能达到类似的效果)。

任何人都可以给我一些暗示吗?我非常感谢任何帮助,或者至少指出自己正确的方向。

4 个答案:

答案 0 :(得分:7)

您可以使用getMapCenter,只需添加或减去纬度范围或经度范围(当然除以2)即可找到边界。

答案 1 :(得分:2)

那些地方标记来自哪里?如果它们来自Web服务,请检查Web服务是否支持空间查询。如果它是一个基本点(矩形包络)你可以做这样的事情:

注意:(xmin,ymin - > xmax,ymax)是矩形(范围)的范围。

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

这很简单。您甚至可以使用Google Maps Data API存储地点标记,并具有执行空间查询的机制。

如果您的数据位于Google App Engine上,那么您可以使用基于GeoPt的查询,也可以滚动自己的空间索引。查看http://code.google.com/p/geomodel/

答案 2 :(得分:2)

我正在做类似于你自己的事情,但我正在使用服务器。我这样做的原因是出于计算原因。当应用程序首次启动时,HTTP请求被发送到包含MySQL查询的php脚本。 php脚本接收用户当前的lat / long并在JSON中返回当前位置1KM内的所有点。然后,应用程序将该JSON解析为本地MySQL数据库并对其进行处理。

要发送HTTP请求并将JSON解析到数据库中,我正在执行以下操作..

  //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());
 }

为了实现这个目的,你所需要的只是一个简短的php文件,它可以像Lat / lng那样......

  <?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();
 ?>

这将获取值并以JSON格式打印结果。

//编辑:首先获取lat / lng我正在使用GPS。

希望这有帮助。

答案 3 :(得分:2)

答案取决于您的标记来自何处。它们是存储在Android设备中还是来自Web服务器? 无论哪种方式,如果您需要同时代表数千个位置,您可能需要实现某种形式的群集,如果标记来自网络,则可以在客户端或服务器上完成。

例如,请参阅此服务器端群集器(2个不同版本):

http://maps.forum.nu/server_side_clusterer

http://maps.forum.nu/server_side_clusterer/index2.php

或客户端聚合器:

http://gmaps-utility-library.googlecode.com/svn/trunk/markerclusterer/1.0/

另一种选择是使用自定义图块(就像谷歌一样),但根据您的确切需要,它可能有点过分。