2

我有一个代表学区的多边形,它是从NYC Open Data导入的。我相信坐标在epsg 投影 2263 - nad83 / 纽约长岛

我无法将坐标转换为谷歌地图可用的格式。

这是我从原始 shapefile 导入多边形的代码:

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

我知道我缺少关于如何转换坐标的一些东西,但我不确定从这里去哪里,即使在阅读了 Daniel Azuma 的优秀指南之后。有人知道怎么做吗?

4

1 回答 1

8

我通常不使用 rgeo 转换数据,但我知道我在坐标系周围的方式,所以 dazuma 的指南对我来说很清楚。

您首先定义 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)

所以简而言之:在不投影几何体的情况下使用正确的工厂进行投射,然后将其投射到想要的坐标系和项目中。由于我们现在指定了 from 和 to,它会起作用。

现在您可以使用 rgeo-geojson gem 将其转换为 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 来存储和维护它时,我使用 geoserver 来有效地托管和查询它(以及前端的 openlayers)。但它确实涉及设置一个额外的组件。所以这取决于你的需求。

于 2014-06-02T22:45:19.630 回答