Создание запроса PostGIS с помощью Rails

Я использую PostGIS (1.5.1) с Rails (3.0.0rc) и Google Map (v3), и я ищу способ запросить базу данных, чтобы получить все точки внутри многоугольника (в частности, границы окна просмотра карты). В настоящее время я отправляю координаты границ на сервер как таковые:

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 geography больше подходит для такого рода запросов, но я не думаю, что такой тип поддерживается 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 и space_adapter в своем проекте, но я изо всех сил пытаюсь найти много информации об их использовании, как я описал выше. Может быть, запрос расстояния будет лучшим подходом? Спасибо!

РЕДАКТИРОВАТЬ: моя миграция выглядит следующим образом:

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

person Budgie    schedule 24.08.2010    source источник


Ответы (3)


Достаньте стандартную карту мира (ноль долготы посередине, линия дат по краям). Нанесите на карту угловые точки вашего ящика. Соедините эти точки, используя только те линии, которые остаются внутри карты. Это поле, которое запрашивает базу данных. Вот почему ваши очки Aus/NZ не выходят из запроса. Вы должны либо использовать тип geography, либо заметить, когда ваше поле пересекает линию даты, и разделить его на два непересекающихся поля запроса.

person Paul Ramsey    schedule 25.08.2010

Спасибо за весь вклад - я боюсь, что на самом деле это оказалось серьезной ошибкой n00b с моей стороны, когда я перепутал корреляцию между x / y и lng / lat, поэтому точки на карте отображались нормально при увеличении. исчезает при увеличении. Я настоятельно рекомендую QGIS (спасибо scw на https://gis.stackexchange.com/ за предложение) для тех, кто начинает работать с ГИС, я сразу увидел ошибку, когда точки были показаны вверх ногами!! Еще раз всем спасибо!

Кстати, немного удивительно, что точки в Новой Зеландии/Австралии отображаются нормально, даже когда ограничивающая рамка пересекает международную линию перемены дат, хотя это может измениться, если я добавлю еще несколько точек в этой области.

person Budgie    schedule 25.08.2010

Могут иметь место два разных типа проекций. Убедитесь, что проекция одинакова в базе данных и в вашем приложении.

person Preston Marshall    schedule 24.08.2010
comment
Спасибо за ваш ответ, я включил миграцию моей базы данных выше, чтобы предоставить более подробную информацию... - person Budgie; 24.08.2010
comment
Хм, это похоже на действительный SRID. Вы проверили, действительно ли точки появляются из выбора SQL? Я бы попытался сузить проблему до базы данных или карт Google. Я обнаружил несколько случаев, когда GMaps не помещал точки в определенное место на карте. - person Preston Marshall; 24.08.2010
comment
Точки в Великобритании и Африке отображаются нормально, но только при определенном уровне масштабирования — около 3 и ниже. Точка в Новой Зеландии и Австралии никогда не отображается, но я предполагаю, что это, возможно, проблема с линией даты... Карты Google, похоже, отлично отправляют границы, я думаю, что это проблема с моим запросом - если я отображаю все точки как JSON (так что без запроса) они отлично отображаются на карте! - person Budgie; 24.08.2010
comment
Хм, может быть проблема с запросом, но, похоже, он работает для другого парня. Может быть, вы могли бы попробовать выполнить запрос с помощью простого sql вместо GeoRuby, по крайней мере, чтобы увидеть, что он возвращает? Вот документы по нему: postgis.refractions.net/documentation/manual -1,5/ - person Preston Marshall; 24.08.2010