- Где я нахожусь?
- В корзине воздушного шара.
Как и обещал
вчера,
поговорим о том, куда девается определение
системы координат (spatialReference)
при передаче FeatureSet
в скрипт геопроцессора
ArcGIS.
Но сначала
закроем вчерашнюю тему, про дырку от
бублика. Я нашел только один способ
автоматически превращать всякую фигню,
нарисованную пользователем, в корректные,
с точки зрения ArcGIS, фигуры. Этот способ
заключается в использовании Geometry
Service «Simplify». И не спрашивайте, почему
он так называется - «упростить». Он
делает ровно то, что мне нужно — превращает
дырки в нормальные полигоны и делает
из самопересекающегося полигона
правильный составной полигон.
Чтобы использовать
этот сервис в прикладухе на ArcGIS
Silverlight API, достаточно написать нечто
вроде
private void evtDrawComplete(object sender, DrawEventArgs e) {
currGeom = e.Geometry;
draw.DrawMode = DrawMode.None;
draw.IsEnabled = false;
try {
var gl = getRLLayer();
var graphic = new ESRI.ArcGIS.Client.Graphic() {
Geometry = currGeom, Symbol = polySymbol
};
gl.Graphics.Add(graphic);
var geometryService = new GeometryService("http://tasks.arcgisonline.com/ArcGIS/rest/services/"+
"Geometry/GeometryServer");
var graphicList = new List<Graphic>();
graphicList.Add(graphic);
geometryService.SimplifyCompleted += (sndr, args) => {
gl.Graphics.Remove(graphic);
graphic.Geometry = args.Results[0].Geometry;
gl.Graphics.Add(graphic);
askGeoprocessor(graphic.Geometry); // send good polygon to geoprocessor
};
geometryService.Failed += (sndr, args) => {
MessageBox.Show("Сбой нормализации полигона: " + args.Error);
};
geometryService.SimplifyAsync(graphicList);
}
catch(Exception ex) {
string msg = string.Format("Сбой отправки запроса: \n [{0}]", ex.Message);
MessageBox.Show(msg);
}
}
|
А теперь таки
про spatialReference.
Фишка в том,
что в Python скрипте
геопроцессора нет доступа к сведениям
о системе координат переданного в скрипт
полигона (используется FeatureSet),
хотя сведения эти передаются явным
образом
inputPolygon={
"geometryType":"esriGeometryPolygon",
"spatialReference":{"wkid":102100},
"features":[{
"geometry":{
"spatialReference":{"wkid":102100},
"rings":[[[7592337.47835702,9803507.48815798],[7924991.42545401,10312272.348424],[8277213.25179201,9979618.40132698],[7592337.47835702,9803507.48815798]]]
},
"attributes":{}
}]}
|
Проведенные
тесты показывают, что где-то глубоко
внутре используемых обьектов эта
информация есть, равно как и координаты
дырки от бублика. Просто через API не
выходит получить прямой доступ к данным.
Но важно не
это, важно другое — что же делать,
трахтибидох? Какой смысл в координатах
если мы не знаем систему координат,
точку отсчета?
На мой взгляд,
сделать можно две вещи: передавать
spatialreference отдельным параметром и/или
трансформировать переданные координаты
в известную и желаемую систему координат.
Второй способ лично мне нравится больше.
Вот смотрите
import arcpy
from arcpy import env
fsetObj = arcpy.GetParameter(0)
fsetDesc = arcpy.Describe(fsetObj)
if hasattr(fsetDesc, 'spatialReference'): log.info("arcpyStuff, input fset spatialReference '%s'" % fsetDesc.spatialReference) # haven't
WKID = 4326 # WGS-1984 http://anothergisblog.blogspot.com/2011/05/spatial-reference-class.html
sr = arcpy.SpatialReference()
sr.factoryCode = WKID
sr.create()
# env.outputCoordinateSystem = sr
# или возьмем spatialreference из заранее подготовленного featureclass
gdbPath = r'''\\cache\MXD\seismo\Seis_button.gdb'''
seisFCName = r'''APP_GP_SEISM2D_L'''
seisDesc = arcpy.Describe(os.path.join(gdbPath, seisFCName))
log.info("arcpyStuff, seismoprofiles WKID '%s'" % (seisDesc.spatialReference.factoryCode))
rows = arcpy.SearchCursor(fsetObj, '', sr) # decimal degree
# rows = arcpy.SearchCursor(fsetObj, '', seisDesc.spatialReference) # meters
for row in rows:
geom = row.shape
log.info("arcpyStuff searchcursor, geometry geojson '%s'" % (geom.__geo_interface__)) # {'type': 'Polygon', 'coordinates': []}
if hasattr(geom, 'spatialReference'): log.info("arcpyStuff searchcursor, geometry spatialReference '%s'" % (geom.spatialReference)) # haven't
if geom.partCount <= 0 or geom.area <=0:
raise NameError("Wrong input polygon, you should send no selfintersected clockwise drawed single ring")
for part in geom:
log.info("arcpyStuff searchcursor, geometry part, len '%s'" % (len(part)))
for pnt in part:
log.info("arcpyStuff searchcursor, point x '%s', y '%s'" % (pnt.X, pnt.Y))
|
Трансформация
происходит (задается) на строке
rows = arcpy.SearchCursor(fsetObj, '', sr) # decimal degree
И, как ни странно, это работает. На входе
имеем
WKID = 102100
geometry geojson '{'type': 'Polygon', 'coordinates': [[(7924991.4255000018, 10390543.865400001), (8257645.3726000004, 9803507.4882000014), (7631473.2368000001, 9901346.8844000027), (7924991.4255000018, 10390543.865400001)]]}'
а на выходе
WKID = 4326
geometry geojson '{'type': 'Polygon', 'coordinates': [[(71.191409240428044, 67.809244466732096), (74.17969049045422, 65.730626450487776), (68.554690489665163, 66.089364228422752), (71.191409240428044, 67.809244466732096)]]}'
Легко проверить, что это одни и те же
координаты, только в разных СК.
original post http://vasnake.blogspot.com/2012/10/spatialreference.html
original post http://vasnake.blogspot.com/2012/10/spatialreference.html
Комментариев нет:
Отправить комментарий