dma*_*ter 2 ruby-on-rails geospatial rgeo
我有一个代表学区的多边形,我从NYC Open Data导入.我相信坐标是在epsg投影2263 - nad83/new york long island
我无法将坐标转换为Google地图可用的格式.
这是我从原始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
Run Code Online (Sandbox Code Playgroud)
在我的模型中:
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
Run Code Online (Sandbox Code Playgroud)
在我的控制器中:
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
Run Code Online (Sandbox Code Playgroud)
我知道我遗漏了一些关于如何转换坐标的东西,但我不知道从哪里开始,即使在读完Daniel Azuma的优秀指南之后.有人知道怎么做吗?
我通常不使用rgeo转换数据,但我知道我的方式绕坐标系统,所以dazuma的指南对我来说非常清楚.
你首先定义WGS84(它将在谷歌地图上渲染得很好,它使用稍微不同的坐标系,但它们完美地映射)
wgs84_proj4 = '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs'
wgs84_factory = RGeo::Geographic.spherical_factory(:srid => 4326, :proj4 => wgs84_proj4)
Run Code Online (Sandbox Code Playgroud)
现在您有一个可以创建WGS84点/几何的工厂.现在使用该工厂转换几何体.
假设您已经使用您指定的工厂创建了几何图形ES_Zone,那么您可以这样做
some_es_zone_wgs84 = RGeo::Feature.cast(some_es_zone, :factory => wgs84_factory, :project => true)
Run Code Online (Sandbox Code Playgroud)
但是如果你从数据库中获取它们,工厂将拥有正确的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)
Run Code Online (Sandbox Code Playgroud)
简而言之:在不投影几何体的情况下投射它以使用正确的工厂,然后将其投射到所需的坐标系和项目中.既然我们现在已经指定了,那么它将起作用.
现在您可以使用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
Run Code Online (Sandbox Code Playgroud)
注意我将我的几何图形从比利时坐标系(EPRS 31370)转换为wgs84(EPRS 4326),并一次性转换为geojson.postgis也知道所有的投影,并且它们被维护,所以我不必弄乱proj4定义.
我使用的另一种替代方案(取决于空间数据的数量)是我使用geoserver来提供空间数据.因此,当我使用rails来存储和维护时,我使用geoserver来有效地托管和查询它(以及前端中的openlayers).但它确实涉及设置一个额外的组件.所以这取决于你的需求.