3

我正在使用带有 Rails (3.0.0rc) 和 Google Map (v3) 的 PostGIS (1.5.1),并且我正在寻找一种方法来查询数据库以检索多边形内的所有点(特别是边界地图视口)。目前我正在将边界坐标发送到服务器,如下所示:

google.maps.event.addListener(map, 'bounds_changed', function() {
  var bounds = map.getBounds();
  var ne = bounds.getNorthEast();
  var sw = bounds.getSouthWest();
  var yMaxLat = ne.lat();
  var xMaxLng = ne.lng();
  var yMinLat = sw.lat();
  var xMinLng = sw.lng();
  //alert("bounds changed");
  updateMap(yMaxLat, xMaxLng, yMinLat, xMinLng);
});

function updateMap(yMaxLat, xMaxLng, yMinLat, xMinLng) {
  jQuery.getJSON("/places", { "yMaxLat": yMaxLat, "xMaxLng": xMaxLng, "yMinLat": yMinLat, "xMinLng": xMinLng }, function(json) {
    if (json.length > 0) {
      for (i=0; i<json.length; i++) {
        var place = json[i];
        var category = json[i].tag;
        addLocation(place,category);
      }
    }
  });
}

然后在我的控制器中:

format.js do
  xMinLng = params[:xMinLng]
  yMinLat = params[:yMinLat]
  xMaxLng = params[:xMaxLng]
  yMaxLat = params[:yMaxLat]

  @map_places = Place.find(:all, :conditions => ["geom && ?", Polygon.from_coordinates([[[xMinLng, yMinLat], [xMinLng, yMaxLat], [xMaxLng, yMaxLat], [xMaxLng, yMinLat], [xMinLng, yMinLat]]], 4326)])
  render :json => @map_places
end

我的查询基于此示例,但它的行为并不像预期的那样 - 当地图缩小时会显示大多数点,但不会显示靠近国际日期变更线的点(即在澳大利亚和新西兰) . 当地图放大时,对于全球的任何区域,这些点根本不会显示。我读过一些关于 PostGIS 的地理类型更适合这种查询的内容,但我认为GeoRuby 不支持这种类型(它由 GeoDjango 支持)。我的控制台针对此类请求的输出如下:

Started GET "/places?yMaxLat=63.93767251746141&xMaxLng=43.033828125&yMinLat=36.88016688406946&xMinLng=-39.407578125" for 127.0.0.1 at Tue Aug 24 12:11:41 +0100 2010
Processing by PlacesController#index as JSON
Parameters: {"xMinLng"=>"-39.407578125", "yMaxLat"=>"63.93767251746141", "xMaxLng"=>"43.033828125", "yMinLat"=>"36.88016688406946"}
Place Load (0.4ms)  SELECT "places".* FROM "places"
Place Load (0.8ms)  SELECT "places".* FROM "places" WHERE (geom && '0103000020E6100000010000000500000052B81E852BB443C0DF0CF74EA970424052B81E852BB443C0686D2EA705F84F40AE47E17A54844540686D2EA705F84F40AE47E17A54844540DF0CF74EA970424052B81E852BB443C0DF0CF74EA9704240')
Completed 200 OK in 136ms (Views: 3.4ms | ActiveRecord: 1.2ms)

构建这样一个查询的最佳方法是什么?我在我的项目中使用了 GeoRuby 和 spatial_adapter gem,但我很难找到很多关于使用它们的信息,如上所述。距离查询可能是更好的方法吗?谢谢!

编辑:我的迁移如下:

class CreatePlaces < ActiveRecord::Migration
  def self.up
    create_table :places do |t|
      t.string :city_name
      t.integer :country_id, :null => false
      t.point :geom, :null => false, :with_z => true, :srid => 4326
      t.string :name, :null => false
      t.string :tag, :null => false

      t.timestamps
    end
add_index :places, :geom, :spatial => true
  end

  def self.down
    drop_table :places
  end
  remove_index :places, :geom
end
4

3 回答 3

3

拿出一张标准的世界地图(中间是零经度,边缘是日期线)。在地图上绘制方框的角点。连接这些点,只使用留在地图内的线。那是查询数据库的框。这就是为什么您的澳大利亚/新西兰积分没有从查询中出来的原因。您必须使用地理类型或注意您的框何时跨越日期线并将其拆分为两个非交叉查询框。

于 2010-08-25T18:02:27.980 回答
1

感谢所有的输入 - 我担心这实际上是我的一个巨大的 n00b 错误,因为混淆了 x/y 和 lng/lat 之间的相关性,因此为什么地图上的点在缩放时显示很好出,但放大时消失了。我会彻底推荐QGIS(感谢https://gis.stackexchange.com/上的scw的建议)对于任何开始使用 GIS 的人,当点显示时我立即看到错误倒挂!!再次感谢大家!

顺便说一句,有点令人惊讶的是,即使边界框越过国际日期变更线,新西兰/澳大利亚的点也能正常显示,尽管如果我在该区域添加更多点,情况可能会改变。

于 2010-08-25T20:35:21.277 回答
0

可能有两种不同类型的投影正在进行。确保数据库和应用程序中的投影相同。

于 2010-08-24T15:12:04.803 回答