RGeo: проецирование полигонов на карту Google с другим SRID

У меня есть многоугольник, представляющий школьный округ, который я импортировал из Открытые данные Нью-Йорка. Я считаю, что координаты находятся в проекции epsg 2263 - nad83 / new Йорк Лонг-Айленд

У меня возникли проблемы с преобразованием координат в формат, используемый Google Maps.

Вот мой код, который импортирует полигоны из исходных шейп-файлов:

proj4 = "+proj=lcc +lat_1=41.03333333333333 +lat_2=40.66666666666666 +lat_0=40.16666666666666 +lon_0=-74 +x_0=300000.0000000001 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192 +no_defs"
factory = RGeo::Geographic.projected_factory(:projection_proj4 => proj4, :projection_srid => 2263)

RGeo::Shapefile::Reader.open("/Users/dmanaster1/flatiron_school/nycdata/db/source/ES_Zones_2013-2014.shp", :factory => factory.projection_factory) do |file|
  file.each do |record|
    school_zone = ES_Zone.new
    ...
    school_zone.geometry = record.geometry
    school_zone.save
  end
  file.rewind
end

В моей модели:

class ES_Zone < ActiveRecord::Base
  proj4 = "+proj=lcc +lat_1=41.03333333333333 +lat_2=40.66666666666666 +lat_0=40.16666666666666 +lon_0=-74 +x_0=300000.0000000001 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192 +no_defs"
  FACTORY = RGeo::Geographic.projected_factory(:projection_proj4 => proj4, :projection_srid => 2263)
  set_rgeo_factory_for_column(:geometry, FACTORY.projection_factory)
end

В моем контроллере:

  def index
    polygons = format_polygon(ES_Zone.first)
    gon.polygons = JSON.parse(polygons.to_json)
  end

  private

  def format_polygon(zone)
    array = Array.new
    zone.geometry.each do |polygon|
      polygon.exterior_ring.points.each do |point|
        x = point.x
        y = point.y
        array << { "lng" => x, "lat" => y }
      end
    end
    [array]
  end

Я знаю, что мне чего-то не хватает в том, как преобразовать координаты, но я не уверен, что делать дальше, даже после прочтения отличное руководство. Кто-нибудь знает, как это сделать?


person dmanaster    schedule 28.05.2014    source источник


Ответы (1)


Обычно я не конвертирую данные с помощью rgeo, но я хорошо разбираюсь в системах координат, поэтому руководство Дазумы было для меня довольно понятным.

Сначала вы определяете WGS84 (который будет прекрасно отображаться поверх Google Maps, который использует немного другую систему координат, но они отлично отображаются)

wgs84_proj4 = '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs'

wgs84_factory = RGeo::Geographic.spherical_factory(:srid => 4326, :proj4 => wgs84_proj4)

Теперь у вас есть фабрика, которая может создавать точки/геометрии WGS84. Теперь используйте эту фабрику для преобразования вашей геометрии.

Предположим, вы создали геометрию с указанной вами фабрикой для своего ES_Zone, тогда вы можете просто сделать

some_es_zone_wgs84 = RGeo::Feature.cast(some_es_zone, :factory => wgs84_factory, :project => true)

Но если вы извлечете их из базы данных, фабрика будет иметь правильный srid, но не правильную proj4 информацию для выполнения этого приведения. Однако это легко исправить:

some_es_zone = ES_Zone.find(params[:id])
some_es_zone_2263  = RGeo::Feature.cast(some_es_zone, :factory => 2263_factory, :project => false)
some_es_zone_wgs84 = RGeo::Feature.cast(some_es_zone, :factory => wgs84_factory, :project => true)

Итак, вкратце: приведите его без проецирования геометрии, чтобы использовать правильную фабрику, а затем приведите его к нужной системе координат и проекту. Поскольку мы сейчас указали от и до, это сработает.

Теперь вы можете использовать гем rgeo-geojson, чтобы преобразовать его в geoJson и отправить в браузер.

Если вы используете postgis, как и я, я обычно просто использую возможности postgis для создания geoJson, который затем включаю на свою страницу и отображаю с помощью листовки.

Итак, я добавляю в свою модель следующий метод:

def as_geojson
  sql = "SELECT ST_asgeojson(ST_Transform(ST_SetSRID(geom,31370),4326)) FROM samples where id = #{self.id};"

  cursor = Sample.connection.execute(sql)
  cursor.first["st_asgeojson"]
end

Обратите внимание, что я преобразовываю свою геометрию из бельгийской системы координат (EPRS 31370) в wgs84 (EPRS 4326) и преобразовываю ее в geojson за один раз. Также postgis знает все проекции, и они поддерживаются, поэтому мне не нужно возиться с определениями proj4.

Другая альтернатива, которую я использую (зависит от количества пространственных данных), заключается в том, что я использую геосервер для обслуживания пространственных данных. Поэтому, пока я использую rails для его хранения и обслуживания, я использую геосервер для эффективного размещения и запросов (и openlayers во внешнем интерфейсе). Но это требует установки дополнительного компонента. Так что это зависит от ваших потребностей.

person nathanvda    schedule 02.06.2014
comment
Никакой обратной связи? - person nathanvda; 08.06.2014
comment
Заметил небольшую недоработку: при выборке геометрии из БД у них будет правильный srid, а у фабрики не будет правильной информации о proj4. Обновил мой ответ соответственно. - person nathanvda; 20.06.2014