 |
www.integro.ru ЦСИ ИНТЕГРО
|
Предыдущая тема :: Следующая тема |
Автор |
Сообщение |
Володченко Станислав
Зарегистрирован: 01.12.2005 Сообщения: 18 Откуда: Питер
|
Добавлено: Пн 11 Июл 2011 17:01 Заголовок сообщения: Очень медленно обрабатывается пространственная выборка объектов |
|
|
Задача такая, есть много точек GPS треккинга маршрутов общественного транспорта. Я их импортирую в ГИС, а вот дальше стоит задача посчитать скорости и привязать их к сегментам УДС. Для этого строю для каждого сегмента УДС буферную зону, делаю выборку точек треккинга по этой зоне и обрабатываю их - записываю идентификатор сегмента в точку треккинга, чтобы в дальнейшем получить возможность сбора статиститки по скоростям.
Делаю примерно так
Код: |
procedure findObj(ObjectId : WideString);
var
k, n : Integer;
angle : Double;
sx, sy, ex, ey, d : Double;
begin
segment := mapObjects.GetObject(ObjectId);
contour := segment.Shapes[0].Contour;
bufcontour := contour.BuildBufferZone(rad);
//selection.DeselectAll;
qryObject := _gIA.ActiveDb.MapObjects;
qry := qryObject.QueryByContour(pointLayerId, bufcontour,
incrIntersected + incrContains,
incrIntersected + incrContains);
while not qry.EOF do begin
selList.Add(qry.ObjectID);
qry.MoveNext;
end;
//
qry := qryObject.QueryByContour(pointLayerId,bufcontour,
incrIntersected + incrContains,
incrIntersected);
while not qry.EOF do begin
selList.Add(qry.ObjectID);
qry.MoveNext;
end;
//
qry:= qryObject.QueryByContour(pointLayerId,bufcontour,
incrIntersected + incrContains,
incrContains);
while not qry.EOF do begin
selList.Add(qry.ObjectID);
qry.MoveNext;
end;
qry:= qryObject.QueryByContour(pointLayerId,bufcontour,
incrContains,
incrContains);
while not qry.EOF do begin
selList.Add(qry.ObjectID);
qry.MoveNext;
end;
//
qry:=qryObject.QueryByContour(pointLayerId, bufcontour,
incrContains + incrTouched,
incrTouched);
while not qry.EOF do begin
selList.Add(qry.ObjectID);
qry.MoveNext;
end;
for k := 0 to pred(selList.Count) do
begin
//обработка объектов
trek := mapObjects.GetObject(selList[k]);
//определение направления
angle := trek.SemData.GetValue('GPS','ANGLE', 0) * Pi / 180;
n := pred(contour.Item[0].VertexCount);
contour.Item[0].GetVertex(0, sx, sy, d);
contour.Item[0].GetVertex(n, ex, ey, d);
AbsoluteAngle(sx,sy,ex,ey,d);
//проверка совпадения
if(abs(angle-d)*180/Pi < deviation) then
trek.SemData.SetValue('GPS','DIR',1, 0)
else
trek.SemData.SetValue('GPS','DIR',2, 0);
//записываем данные о родителе
trek.SemData.SetValue('GPS','ID_OBJECT',segment.ID, 0);
end;
end;
|
трассировка показывает, что узкое место в пространственных запросах и их обработке, можно ли ускорить процесс.
Количество сегментов 6700
Количество точек треккинга ~360000
Клиент
ГИС - 4.4.0.226
Delphi 6
WinXP SP3
Сервер
MS SQL 2008
подключение модуля, через старый механизм Addon2M, в виде инпроц сервера (dll)
Заранее благодарен за советы! |
|
Вернуться к началу |
|
 |
APopov
Зарегистрирован: 19.06.2006 Сообщения: 347 Откуда: Самара
|
Добавлено: Пн 11 Июл 2011 20:35 Заголовок сообщения: |
|
|
1) получение угла сегмента нужно вынести за цикл. это самый очевидный шаг.
Код: | //определение направления
n := pred(contour.Item[0].VertexCount);
contour.Item[0].GetVertex(0, sx, sy, d);
contour.Item[0].GetVertex(n, ex, ey, d);
AbsoluteAngle(sx,sy,ex,ey,d);
|
2) непонятно зачем столько запросов, чтобы собрать интерeсующие точки?
как по мне, хватило бы одного : Код: | qry := qryObject.QueryByContour(pointLayerId, bufcontour, incrIntersected, incrIntersected); |
3) основную пространственную транзакцию, через которую вы делаете изменения, можно переодически коммитить и получать заново. это для того чтоб она не распухала за счет своего внутреннего кеша. например так: Код: | for k := 0 to pred(selList.Count) do
begin
//...
if (k mod 500)=0 then begin
mapObjects.UpdateChanges;
mapObjects := _gIA.ActiveDb.MapObjects;
end;
end;
|
_________________ ОАО "Самара-Информспутник",
инженер-программист Попов Артем |
|
Вернуться к началу |
|
 |
Володченко Станислав
Зарегистрирован: 01.12.2005 Сообщения: 18 Откуда: Питер
|
Добавлено: Пн 11 Июл 2011 22:35 Заголовок сообщения: |
|
|
Спасибо!
Первый шаг да, он очевиден, я что-то не подумал про него, исправлю.
Второй пункт по поводу пространственного запроса, это я пришел опытным путем, потому что иначе не все объекты попадают в буфф зону, надо чтобы попадали те, которые и содержаться и пересекают и касаются, для этого сделаны те маски пространственных отношений.
Третий шаг, он есть во внешней процедуре, коммит производится именно через 500 объектов, другой вопрос, что у сегмента может больше 500 связанных объектов и от этого тоже может пухнуть транзакция.
Завтра попробую, отпишусь по результатам.
Еще раз спасибо! |
|
Вернуться к началу |
|
 |
andreichernov
Зарегистрирован: 14.02.2005 Сообщения: 209 Откуда: Самара
|
Добавлено: Вт 12 Июл 2011 19:30 Заголовок сообщения: |
|
|
Столько запросов Вам точно не надо.
GPS-Точки ведь точечный объект. Хватит и запрос на попадание в буферную зону (contains).
----
Однако таким способом вряд ли Вы кардинально увеличите скорость.
Кроме того, некоторые точки (на перекрестках) будут относиться к нескольким контурам.
Я бы организовал по другому работу.
Внешний цикл не по сегментам сети, а по точкам.
Вокруг точки строил бы буфер, находил через intersect пересечение его с сегментами сети.
Далее из сегментов сети (если их несколько) выбирал ближайший через IngeoContour.DistanceFromPoint.
При этом совершенно необязательно импортировать точки как объекты Ингео (но необходимость этого зависит от задачи, скорее всего Вам нужно просто посчитать среднюю скорость или загруженность по сегментам сети - статистику набрать). |
|
Вернуться к началу |
|
 |
|
|
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете голосовать в опросах Вы не можете добавлять приложения в этом форуме Вы можете скачивать файлы в этом форуме
|
|