Список форумов www.integro.ru www.integro.ru
ЦСИ ИНТЕГРО
 
 FAQFAQ   ПоискПоиск   ПользователиПользователи   ГруппыГруппы   РегистрацияРегистрация 
 ПрофильПрофиль   Войти и проверить личные сообщенияВойти и проверить личные сообщения   ВходВход 

Очень медленно обрабатывается пространственная выборка объектов

 
Начать новую тему   Ответить на тему    Список форумов 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.

При этом совершенно необязательно импортировать точки как объекты Ингео (но необходимость этого зависит от задачи, скорее всего Вам нужно просто посчитать среднюю скорость или загруженность по сегментам сети - статистику набрать).
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Показать сообщения:   
Начать новую тему   Ответить на тему    Список форумов www.integro.ru -> Вопросы разработчиков Часовой пояс: GMT + 5
Страница 1 из 1

 
Перейти:  
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете добавлять приложения в этом форуме
Вы можете скачивать файлы в этом форуме


© phpBB Group
Русская поддержка phpBB