На главную... Продукты | Технологии | Классификаторы | Проекты | Скачать | Цены| Форум | Статьи | Обучение | Контакты

Выделение нескольких областей в GIS WebToolkit SE 6.18.0

Поиск  Пользователи  Правила  Войти
Форум » Серверные приложения » GIS WebToolKit
Страницы: 1
RSS
Выделение нескольких областей в GIS WebToolkit SE 6.18.0
 
Добрый день.
Мы на основе src\components\GwtkSearchArea\actions\SelectMapCircleAction.ts и src\components\GwtkSearchArea\actions\SelectMapPolygonAction­.ts сделали компоненты по выделение произвольной области и окружности.
Как можно сделать так, что бы  можно было выделять много областей, а не одну. То есть например после окончания выделения полигона(окружности), можно сразу рисовать следующий полигон(окружность), и старый не удалялся .
 
Цитата
Михаил Перевёрткин написал:
Добрый день.
Мы на основе src\components\GwtkSearchArea\actions\SelectMapCircleAction.ts и src\components\GwtkSearchArea\actions\SelectMapPolygonAction­ ­.ts сделали компоненты по выделение произвольной области и окружности.
Как можно сделать так, что бы  можно было выделять много областей, а не одну. То есть например после окончания выделения полигона(окружности), можно сразу рисовать следующий полигон(окружность), и старый не удалялся .
Добрый день,

После создания очередной области необходимо сохранить метрику для дальнейшей отрисовки. Сделать это можно несколькими способами.

Первый вариант с одним объектом карты - использовать геометрию типа "мульти-полигон" и добавлять области в него как отдельные метрики полигонов.
Объект добавить в отрисовку (в метод postRender задачи или обработчика). Тогда будет рисоваться 1 объект карты в виде мульти-полигона.

Второй способ - использовать объект нанесенной области с геометрией "полигон" (либо создавать его копию в виде нового объекта карты ) и добавлять в массив.
Массив объектов добавить в отрисовку. Тогда будут рисоваться все объекты отдельно в виде полигонов.
 
Цитата
Виктор Тазин написал:
Цитата
Михаил Перевёрткин написал:
Добрый день.
Мы на основе src\components\GwtkSearchArea\actions\SelectMapCircleAction.ts и src\components\GwtkSearchArea\actions\SelectMapPolygonAction­ ­ ­.ts сделали компоненты по выделение произвольной области и окружности.
Как можно сделать так, что бы  можно было выделять много областей, а не одну. То есть например после окончания выделения полигона(окружности), можно сразу рисовать следующий полигон(окружность), и старый не удалялся .
Добрый день,

После создания очередной области необходимо сохранить метрику для дальнейшей отрисовки. Сделать это можно несколькими способами.

Первый вариант с одним объектом карты - использовать геометрию типа "мульти-полигон" и добавлять области в него как отдельные метрики полигонов.
Объект добавить в отрисовку (в метод postRender задачи или обработчика). Тогда будет рисоваться 1 объект карты в виде мульти-полигона.

Второй способ - использовать объект нанесенной области с геометрией "полигон" (либо создавать его копию в виде нового объекта карты ) и добавлять в массив.
Массив объектов добавить в отрисовку. Тогда будут рисоваться все объекты отдельно в виде полигонов.
А можно подсказать как именно корректно работать с мультиполигоном.
В руководстве программиста ПАРБ.00167-01 33 01 не вижу такого раздела.

Раньше насколько я понимаю
1, Брался объект mapObject, если его нет создавался
2. Дальше рисуется объект( через addGeoPoint или интерфейс)
3. Потом this.map.setActiveObject(добавление этого объекта)

А как это делается при работе с мультиполигоном?
 
Цитата
Михаил Перевёрткин написал:
А можно подсказать как именно корректно работать с мультиполигоном.
В руководстве программиста ПАРБ.00167-01 33 01 не вижу такого раздела.

Раньше насколько я понимаю
1, Брался объект mapObject, если его нет создавался
2. Дальше рисуется объект( через addGeoPoint или интерфейс)
3. Потом this.map.setActiveObject(добавление этого объекта)

А как это делается при работе с мультиполигоном?
Мульти-полигон - тип геометрии объекта mapObject (наравне с полигоном, линией...).

Работа с ним такая же, как и с текущим объектом рисования.
Только при создании у него указывается тип геометрии MapObjectType.MultiPolygon.

Что в дальнейшем позволяет добавлять точки по селектору ( addGeoPoint(geoPoint: GeoPoint, selector?: PointSelector)) с указанием разных objectNumber (номер полигона в геометрии).

То есть можно либо сразу использовать его при рисовании (хранить дополнительно номер полигона для селектора добавления точки), либо создать новый MapObject и использовать в качестве хранилища линий отрисовки (копировать точки с текущего объекта рисования в новый полигон геометрии).


P.S. Второй способ с массивом объектов проще в реализации - просто храним копии объектов и перерисовываем все при необходимости.
 
Цитата
Виктор Тазин написал:
Цитата
Михаил Перевёрткин написал:
А можно подсказать как именно корректно работать с мультиполигоном.
В руководстве программиста ПАРБ.00167-01 33 01 не вижу такого раздела.

Раньше насколько я понимаю
1, Брался объект mapObject, если его нет создавался
2. Дальше рисуется объект( через addGeoPoint или интерфейс)
3. Потом this.map.setActiveObject(добавление этого объекта)

А как это делается при работе с мультиполигоном?
Мульти-полигон - тип геометрии объекта mapObject (наравне с полигоном, линией...).

Работа с ним такая же, как и с текущим объектом рисования.
Только при создании у него указывается тип геометрии MapObjectType.MultiPolygon.

Что в дальнейшем позволяет добавлять точки по селектору ( addGeoPoint(geoPoint: GeoPoint, selector?: PointSelector)) с указанием разных objectNumber (номер полигона в геометрии).

То есть можно либо сразу использовать его при рисовании (хранить дополнительно номер полигона для селектора добавления точки), либо создать новый MapObject и использовать в качестве хранилища линий отрисовки (копировать точки с текущего объекта рисования в новый полигон геометрии).


P.S. Второй способ с массивом объектов проще в реализации - просто храним копии объектов и перерисовываем все при необходимости.


Вот как пробую я. Компонент по введенной долготой, широтой и радиусом  рисует окружность:
Код
    private circleObject = new MapObject(        new VectorLayer(this.map, {
            alias: '',
            id: Utils.generateGUID(),
            url: '',
        }),
        MapObjectType.MultiPolygon,
        { local: LOCALE.Plane }
    );


    drawObject(value: any) {
  
        const  pointSelector: PointSelector = { contourNumber: this.circleCount++ };

        const center = this.map.geoToPixel(
            new GeoPoint(value.longitude, value.latitude, 0, this.map.ProjectionId),
            this.mapWindow.getMap().getZoom()
        );
        let radius_meter = value.radius * 1000 || 0;
        const latitude = Number(value.latitude) || 0.1;
        const longitude = Number(value.longitude)|| 0.1;
        const mapCalculator = new GWTK.MapCalculations(this.map);
        const pointXYComp = mapCalculator.mapDirectPositionComputation(latitude, longitude, 0, 0);
        const pointGeo = new GeoPoint(pointXYComp.l, pointXYComp.b);
        const pointXY = pointGeo.toMapPoint();
        this.customFields = { radius_meter, pointXY };

        for (let numberPoint = 0; numberPoint < 361; numberPoint = numberPoint + 10) {
            const positions = mapCalculator.mapDirectPositionComputation(latitude, longitude, numberPoint, radius_meter);
            if (positions) {
                console.log(pointSelector);
                this.circleObject.addGeoPoint(new GeoPoint(positions.l, positions.b), pointSelector);
            }
        }

        //this.circleObject.closeObject();


        this.map.setActiveObject(this.circleObject);

        // Показать значение радиуса
        this.showLabel(center.x, center.y, radius_meter);

        //this.map.fitBounds(this.circleObject.getBounds());
    }

При выполнении метода ошибка
Код
Cannot read properties of undefined (reading 'map')
TypeError: Cannot read properties of undefined (reading 'map')
    at MultiLineGeometry.getPointListForDrawing (eval at ./GIS WebToolKit SE/debug/source/mapobject/geometry/MultiLineGeometry.ts (http://localhost:8080/js/app.js:3705:1), <anonymous>:193:54)
    at MultiPolygonGeometry.getPointListForDrawing (eval at ./GIS WebToolKit SE/debug/source/mapobject/geometry/MultiPolygonGeometry.ts (http://localhost:8080/js/app.js:3727:1), <anonymous>:140:123)
    at MapObject.getPointListForDrawing (eval at ./GIS WebToolKit SE/debug/source/mapobject/MapObject.ts (http://localhost:8080/js/app.js:3650:1), <anonymous>:965:26)
    at Function.eval (eval at ./GIS WebToolKit SE/debug/source/renderer/SVGrenderable.ts (http://localhost:8080/js/app.js:3826:1), <anonymous>:192:32)
    at step (webpack-internal:///./node_modules/tslib/tslib.es6.mjs:181:21)
    at Object.eval [as next] (webpack-internal:///./node_modules/tslib/tslib.es6.mjs:162:51)
    at eval (webpack-internal:///./node_modules/tslib/tslib.es6.mjs:155:69)
    at new Promise (<anonymous>)
    at __awaiter (webpack-internal:///./node_modules/tslib/tslib.es6.mjs:151:10)
    at SVGrenderable.createGroupNode (eval at ./GIS WebToolKit SE/debug/source/renderer/SVGrenderable.ts (http://localhost:8080/js/app.js:3826:1), <anonymous>:187:61)
 
Цитата
Михаил Перевёрткин написал:

Вот как пробую я. Компонент по введенной долготой, широтой и радиусом  рисует окружность:
Код
     private circleObject = new MapObject(        new VectorLayer(this.map, {
            alias: '',
            id: Utils.generateGUID(),
            url: '',
        }),
        MapObjectType.MultiPolygon,
        { local: LOCALE.Plane }
    );


    drawObject(value: any) {
  
        const  pointSelector: PointSelector = { contourNumber: this.circleCount++ };

        const center = this.map.geoToPixel(
            new GeoPoint(value.longitude, value.latitude, 0, this.map.ProjectionId),
            this.mapWindow.getMap().getZoom()
        );
        let radius_meter = value.radius * 1000 || 0;
        const latitude = Number(value.latitude) || 0.1;
        const longitude = Number(value.longitude)|| 0.1;
        const mapCalculator = new GWTK.MapCalculations(this.map);
        const pointXYComp = mapCalculator.mapDirectPositionComputation(latitude, longitude, 0, 0);
        const pointGeo = new GeoPoint(pointXYComp.l, pointXYComp.b);
        const pointXY = pointGeo.toMapPoint();
        this.customFields = { radius_meter, pointXY };

        for (let numberPoint = 0; numberPoint < 361; numberPoint = numberPoint + 10) {
            const positions = mapCalculator.mapDirectPositionComputation(latitude, longitude, numberPoint, radius_meter);
            if (positions) {
                console.log(pointSelector);
                this.circleObject.addGeoPoint(new GeoPoint(positions.l, positions.b), pointSelector);
            }
        }

        //this.circleObject.closeObject();


        this.map.setActiveObject(this.circleObject);

        // Показать значение радиуса
        this.showLabel(center.x, center.y, radius_meter);

        //this.map.fitBounds(this.circleObject.getBounds());
    } 

При выполнении метода ошибка
Код
 Cannot read properties of undefined (reading 'map')
TypeError: Cannot read properties of undefined (reading 'map')
    at MultiLineGeometry.getPointListForDrawing (eval at ./GIS WebToolKit SE/debug/source/mapobject/geometry/MultiLineGeometry.ts (http://localhost:8080/js/app.js:3705:1), <anonymous>:193:54)
    at MultiPolygonGeometry.getPointListForDrawing (eval at ./GIS WebToolKit SE/debug/source/mapobject/geometry/MultiPolygonGeometry.ts (http://localhost:8080/js/app.js:3727:1), <anonymous>:140:123)
    at MapObject.getPointListForDrawing (eval at ./GIS WebToolKit SE/debug/source/mapobject/MapObject.ts (http://localhost:8080/js/app.js:3650:1), <anonymous>:965:26)
    at Function.eval (eval at ./GIS WebToolKit SE/debug/source/renderer/SVGrenderable.ts (http://localhost:8080/js/app.js:3826:1), <anonymous>:192:32)
    at step (webpack-internal:///./node_modules/tslib/tslib.es6.mjs:181:21)
    at Object.eval [as next] (webpack-internal:///./node_modules/tslib/tslib.es6.mjs:162:51)
    at eval (webpack-internal:///./node_modules/tslib/tslib.es6.mjs:155:69)
    at new Promise (<anonymous>)
    at __awaiter (webpack-internal:///./node_modules/tslib/tslib.es6.mjs:151:10)
    at SVGrenderable.createGroupNode (eval at ./GIS WebToolKit SE/debug/source/renderer/SVGrenderable.ts (http://localhost:8080/js/app.js:3826:1), <anonymous>:187:61) 

В текущем примере круг добавляется в виде нового контура для первого полигона геометрии (то есть второй и последующие контуры будут считаться вырезом для первого).

Для добавления самостоятельного контура в селекторе нужно использовать номер объекта:
Код
  const  pointSelector: PointSelector = { objectNumber: this.circleCount++ };

Ошибка же предположительно возникает из-за свойства this.circleCount - оно проинициализировано числом (0)?
 
Когда рисую через addGeoPoint теперь все делается корректно.
А как сделать, что бы в компоненте сделанном на основе src\components\GwtkSearchArea\actions\SelectMapPolygonAction­­.ts(src\components\GwtkSearchArea\task\GwtkSearchAreaTask.ts  можно было рисовать несколько полигонов?
Я прописал в GwtkSearchAreaTask

       this.mapObject = new MapObject( this.vectorLayer, MapObjectType.MultiPolygon );

Но в какой момент тут можно установить objectNumber и  как сделать, что бы после окончания выделения области можно было рисовать область заново, не знаю.
Насколько понимаю action начала и окончания рисования происходит здесь

   setAction( id: string, active: boolean ) {
       if ( active ) {
           this.widgetProps.actionId = id;
           this.doAction( id );
       } else {
           this.quitAction( id );
           this.widgetProps.actionId = '';
           this.mapObject.removeAllPoints(); -- Эту строку я удаляю, что бы выделенная область не удалилась, но вот как начать заново рисование?
       }
   }
 
Цитата
Михаил Перевёрткин написал:
Когда рисую через addGeoPoint теперь все делается корректно.А как сделать, что бы в компоненте сделанном на основе src\components\GwtkSearchArea\actions\SelectMapPolygonAction­­­.ts(src\components\GwtkSearchArea\task\GwtkSearchAreaTask.ts  можно было рисовать несколько полигонов?Я прописал в GwtkSearchAreaTask
Добрый день!
В продолжение Вашей мысли вместо строки:
this.mapObject.updateFrom( value as MapObject );
можно написать:
const objectNumber = this.mapObject.getObjectSubObjectsCount();
(value as MapObject).getPointList().forEach(point =>
   this.mapObject.addPoint(point, {
       objectNumber}));
тогда каждая выделенная область будет записана в this.mapObject в отдельный подобъект.
Продолжить рисование можно снова нажав на кнопку "Область".
Чтобы каждый раз отрисовывался весь this.mapObject, нужно переопределить функцию onPostRender:
onPostRender(renderer: SVGrenderer) {
       super.onPostRender(renderer);
       if (this.mapObject.hasPoints()) {
           this.map.mapObjectsViewer.drawMapObject(renderer, this.mapObject);
       }
   }
Изменено: Елена Кузнецова - 09.04.2024 12:44:10
 
Цитата
Елена Кузнецова написал:
Цитата
Михаил Перевёрткин написал:
Когда рисую через addGeoPoint теперь все делается корректно.А как сделать, что бы в компоненте сделанном на основе src\components\GwtkSearchArea\actions\SelectMapPolygonAction­ ­­­.ts(src\components\GwtkSearchArea\task\GwtkSearchAreaTask.ts  можно было рисовать несколько полигонов?Я прописал в GwtkSearchAreaTask
Добрый день!
В продолжение Вашей мысли вместо строки:
this.mapObject.updateFrom( value as MapObject );
можно написать:
const objectNumber = this.mapObject.getObjectSubObjectsCount();
(value as MapObject).getPointList().forEach(point =>
   this.mapObject.addPoint(point, {
       objectNumber}));
тогда каждая выделенная область будет записана в this.mapObject в отдельный подобъект.
Продолжить рисование можно снова нажав на кнопку "Область".
Чтобы каждый раз отрисовывался весь this.mapObject, нужно переопределить функцию onPostRender:
onPostRender(renderer: SVGrenderer) {
       super.onPostRender(renderer);
       if (this.mapObject.hasPoints()) {
           this.map.mapObjectsViewer.drawMapObject(renderer, this.mapObject);
       }
   }
А если нам нужно один раз нажать на область. А потом:

1. Нарисовали полигон
2. Как закончилось рисование полигона, можно сразу рисовать следующий. И так пока  не деактивировал компонент

Или это имеется в виду этот кусок:


onPostRender(renderer: SVGrenderer) {
super.onPostRender(renderer);
if (this.mapObject.hasPoints()) {
this.map.mapObjectsViewer.drawMapObject(renderer, this.mapObject);
}
}
 
Цитата
Михаил написал:
если нам нужно один раз нажать на область. А потом:
Можем предложить другое решение. Все прежние правки отменить. Внести изменение в следующие два файла:
1) GIS WebToolKit SE/debug/source/systemActions/AppendPointAction.ts
   onMouseDown(event: MouseDeviceEvent) {
       if (event.pressedMouseButtonList[2]) {
           this.dashedObject.removeAllPoints();
       }
   }
onMouseClick( event: MouseDeviceEvent ) {
       if ( this.currentObject ) {
           const objectNumber = (this.currentObject.getObjectSubObjectsCount() - 1) > 0 ? this.currentObject.getObjectSubObjectsCount() - 1 : 0;
           const contourNumber = (this.currentObject.getObjectContoursCount(objectNumber) - 1) > 0 ? this.currentObject.getObjectContoursCount(objectNumber) - 1 : 0;
           const selector = { objectNumber, contourNumber };. . .            

           if ( hoverPoint ) {
               this.currentObject.addPoint( hoverPoint, selector );

               this.dashedObject.updatePoint( hoverPoint, {
                   positionNumber: 0,
                   objectNumber: 0,
                   contourNumber: 0
               } );
           } else {
               this.currentObject.addPixelPoint( event.mousePosition, selector );

   . . .

           this.updateWidgetParams();
       }
   }

1.1) добавили метод onMouseDown
1.2) в метод onMouseClick внесли следующие изменения:
- определили три константы (objectNumber, contourNumber, selector)
- в условии if (hoverPoint) заменили this.selector на selector

2) src/components/GwtkSearchArea/actions/SelectMapPolygonAction­.ts

   onMouseDown(event: MouseDeviceEvent): void {
       if (this.currentObject && event.pressedMouseButtonList[2]) {
           const objectNumber = (this.currentObject.getObjectSubObjectsCount() - 1) > 0 ? this.currentObject.getObjectSubObjectsCount() - 1 : 0;
           const contourNumber = (this.currentObject.getObjectContoursCount(objectNumber) - 1) > 0 ? this.currentObject.getObjectContoursCount(objectNumber) - 1 : 0;
           if (this.currentObject.getContourPointsCount(objectNumber, contourNumber) >= 4) {
               this.currentObject?.addEmptyContour(this.currentObject.getObjectSubObjectsCount() - 1);
               super.onMouseDown(event);
           }
       }
   }

2.1) добавили метод onMouseDown

Последовательность действий пользователя:
1. открыть компонент "Поиск по области";
2. нажать кнопку "Область";
3. левой кнопкой мыши задать область (минимум три точки);
4. правой кнопкой мыши завершить рисование текущей области;
5. левой кнопкой мыши задать следующую область;
6. правой кнопкой мыши завершить рисование текущей области;
7. повторить пункты 3 и 4 необходимое количество раз;
8. для завершения нанесения областей и запуска поиска нажать на кнопку "Завершить" (или сделать двойной клик левой кнопкой мыши).
Изменено: Елена Кузнецова - 10.04.2024 14:36:10
Страницы: 1
Читают тему (гостей: 1)



© КБ Панорама, 1991-2025

Регистрируясь или авторизуясь на форуме, Вы соглашаетесь с Политикой конфиденциальности