Статьи

OpenMap Tutorial 4 — Слои

1. Введение

В первом уроке мы создали базовое ГИС-приложение OpenMap, которое отображает карту с одним слоем фигур , загруженным из файловой системы, внутри JFrame . Этот учебник был основан на com.bbn.openmap.app.example.SimpleMap . Во втором уроке мы расширили наше базовое приложение для использования MapHandler а в третьем уроке мы увидели, как оно использует openmap.properties для соединения всего вместе. В этом уроке мы поговорим о слоях карты.

2. Обзор слоев карты

В уроке 1 мы увидели, как добавить ShapeLayer в MapBean . OpenMap поддерживает большое количество типов слоев, которые можно добавить в MapBean как показано на рисунке 1 .

BufferedLayerMapBean — это MapBean который использует BufferedLayer (см. Рисунок 1 ) для создания изображения для некоторых слоев. Он использует флаг фона Layer чтобы определить, какие слои следует добавить к этому буферизованному изображению. Любой слой, который не отвечает на MouseEvent должен быть обозначен как фоновый слой, чтобы уменьшить нагрузку при обработке метода paint() на приложение.

OMGraphicHandlerLayer — это класс базового уровня, который реализует наиболее распространенную функциональность уровня, который должен взаимодействовать и совместно использовать OMGraphic . GraticuleLayer создает свои OMGraphic внутри, а ShapeLayer считывает данные из файла. DTEDLayer и RpfLayer имеют кэши изображений. Существуют специальные слои, которые позволяют вам получить доступ к пространственной базе данных для создания OMGraphic . Любая техника управления графикой может быть использована внутри слоя.

Как базовый класс, OMGraphicHandlerLayer имеет встроенные возможности, которые облегчают управление OMGraphic в слое. Расширяя OMGraphicHandlerLayer , реализуйте метод prepare() чтобы вернуть OMGraphicList содержащий OMGraphic s, соответствующий проекции, установленной в данный момент в слое. Вся работа по сбору, подготовке и генерации OMGraphic должна выполняться в методе prepare() . OMGraphicHandlerLayer также имеет встроенный объект SwingWorker который можно использовать для вызова prepare() в отдельном потоке. Поток SwingWorker можно запустить, вызвав метод doPrepare() . Если SwingWorker уже занят при doPrepare() метода doPrepare() , новый поток будет запущен для вызова prepare() после завершения исходного потока. В стандартной реализации метода prepare() текущий список просто генерируется с текущей проекцией и возвращается.

Рисунок 1: Иерархия классов слоев OpenMap

Рисунок 1: Иерархия классов слоев OpenMap

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

OpenMap также предоставляет несколько слоев для обучения ( com.bbn.openmap.layer.learn ):

  • BasicLayer
  • InteractionLayer
  • SimpleAnimationLayer
  • ProjectionResponsiveLayer

а также тестовые слои ( com.bbn.openmap.layer.test ):

  • BoundsTestLayer
  • GeoCrossDemoLayer
  • GeoIntersectionLayer
  • GeoTestLayer
  • HelloWorldLayer
  • TestLayer

Наконец, com.bbn.openmap.layer.DemoLayer является примером того, как слой может использовать OMDrawingTool для редактирования OMGraphic . Он использует инструмент рисования для создания областей на карте, которые используются в качестве фильтров для управления тем, какие из его OMGraphic также видны.

Слои происходят от java.awt.Component и они являются единственными компонентами, которые могут быть добавлены в MapBean . Поскольку MapBean — это Component содержащиеся в контейнере MapBean , рендеринг Layer на карту контролируется механизмом рендеринга компонентов Java. Этот механизм контролирует, как слоистые компоненты окрашены друг на друга. Чтобы убедиться, что каждый компонент отображается в окне в правильном порядке, класс Component включает метод, который позволяет ему сообщать механизму рендеринга, что он хотел бы быть нарисованным. Эта функция позволяет слоям работать независимо друг от друга и позволяет MapBean не знать, что происходит на MapBean .

Слои в приложении OpenMap могут использовать данные из многих источников:

  • Вычисляя их
  • Из файлов данных локального жесткого диска
  • Из файлов данных из URL
  • Из файлов данных, содержащихся в jar-файле
  • Использование информации, полученной из базы данных (JDBC)
  • Использование информации, полученной от картографического сервера (изображения или объекты карты)

2.1 Создание слоев

Давайте начнем с самых простых слоев. Уже из Tutorial 1 мы увидели, как создать ShapeLayer и добавить его в MapBean . Но начиная с Tutorial 3 мы openmap.properties мощью openmap.properties и MapHandler . Вот изменения, которые вам нужно сделать.

Листинг 1 — openmap.properties

01
02
03
04
05
06
07
08
09
10
11
...
# These layers are turned on when the map is first started.  Order
# does not matter here...
openmap.startUpLayers=basic graticule shapePolitical
# Layers listed here appear on the Map in the order of their names.
openmap.layers=basic graticule shapePolitical
 
# Basic Layer
basic.class=com.bbn.openmap.layer.learn.BasicLayer
basic.prettyName=Basic
...

В качестве краткого напоминания openmap.layers ссылается на загружаемые слои, а openmap.startUpLayers ссылается на те, которые должны быть загружены при запуске. Вы заметите, что basic слой был добавлен.

Результат можно визуализировать на рисунке 2. Из BasicLayer BasicLayer мы узнаем, что он расширяет OMGraphicHandlerLayer , который содержит хорошую функциональность, но предоставляет только методы, необходимые для начала добавления объектов ( OMGraphic s) на карту. Это слой, в котором объекты никогда не меняются, а объекты карты, используемые этим слоем, никогда не меняются. Они всегда управляются и рисуются, даже если они находятся за пределами видимой карты. Когда проекция изменяется, OMGraphic получают сообщение о том, что такое новая проекция, чтобы они могли изменить OMGraphic положение, и затем они перерисовываются. Если вы хотите больше узнать о взаимодействии с вашими OMGraphic после того, как вы OMGraphic их эффективно отображать, перейдите на OMGraphic InteractionLayer .

Слои реализуют интерфейс ProjectionListener для прослушивания ProjectionEvent . Когда проекция изменяется, им может понадобиться повторно извлечь, восстановить их графику, а затем перерисовать себя в новом виде. Мы расскажем больше о проектировании в следующем уроке.

BasicLayer переопределяет два метода из OMGraphicHandlerLayer :

  • prepare() : этот метод вызывается при добавлении слоя на карту или при изменении проекции карты. Нам нужно убедиться, что OMGraphicList возвращаемый этим методом, является тем, что мы хотим нарисовать на карте. OMGraphic должны быть сгенерированы с текущей проекцией. Мы проверяем нулевой OMGraphicList в слое, чтобы увидеть, нужно ли нам создавать OMGraphic s. Этот слой не меняет свои OMGraphic для разных проекций, если ваш слой делает это, вам нужно очистить OMGraphicList и добавить OMGraphics вы хотите для текущей проекции.
  • init() : вызывается из метода prepare() если слой обнаруживает, что его OMGraphicList равен null .
Рисунок 2: Базовый слой

Рисунок 2: Базовый слой

Листинг 2 — метод prepare ()

1
2
3
4
5
6
7
8
public synchronized OMGraphicList prepare() {
      OMGraphicList list = getList();
      if (list == null) {
         list = init();
      }
      list.generate(getProjection());
      return list;
   }

getList() возвращает все, что было возвращено из этого метода при последнем вызове prepare() . В этом примере мы всегда возвращаем объект OMGraphicList , поэтому, если он null , prepare() не был вызван. В этом случае вызывается init() .

Перед возвратом списка объектов карты, вызов для установки проекции слоя имеет решающее значение! OMGraphic нужно сказать, где рисовать себя, и они OMGraphic это, когда им передается текущая Projection в вызове generate(Projection) . Если OMGraphic изменилось, его нужно будет восстановить перед тем, как он будет отрендерен, иначе он не будет отрисовываться сам. У вас может возникнуть проблема генерации, когда OMGraphic появляются с изменениями проекции (масштабирование и панорамирование), но не в любое другое время после каких-либо изменений в OMGraphic . Если вы хотите быть более эффективным, вы можете заменить этот вызов списка в качестве предложения else для проверки (list == null) выше, и вызывать generate(Projection) для всех OMGraphics в методе init() ниже, так как вы создать их. Это предотвратит OMGraphicList.generate(Projection) создания дополнительного цикла через все OMGraphic прежде чем они будут возвращены.

Листинг 3 — метод init ()

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public OMGraphicList init() {
      OMGraphicList omList = new OMGraphicList();
 
      // Add an OMLine
      OMLine line = new OMLine(40f, -145f, 42f, -70f, OMGraphic.LINETYPE_GREATCIRCLE);
      // line.addArrowHead(true);
      line.setStroke(new BasicStroke(2));
      line.setLinePaint(Color.red);
      line.putAttribute(OMGraphicConstants.LABEL, new OMTextLabeler("Line Label"));
 
      omList.add(line);
 
      // Add a list of OMPoints.
      OMGraphicList pointList = new OMGraphicList();
      for (int i = 0; i < 100; i++) {
         OMPoint point = new OMPoint((float) (Math.random() * 89f), (float) (Math.random() * -179f), 3);
         point.setFillPaint(Color.yellow);
         point.setOval(true);
         pointList.add(point);
      }
      omList.add(pointList);
      return omList;  
  }

Метод init() вызывается, когда prepare() возвращает null . Он создает объекты ( OMGraphic ), которые будут добавлены к слою.

В качестве краткого руководства типичное ГИС-приложение состоит из карты ( MapBean в OpenMap), которая состоит из слоев (объектов Layer ), которые состоят из объектов ( OMGraphic ). На следующем рисунке показана иерархия классов OMGraphic s.

Рисунок 3: иерархия классов OMGraphics

Рисунок 3: иерархия классов OMGraphics

Код в листинге 3 создает OMLine и 100 OMPoint . OMGraphic — это объекты растровой и векторной графики, которые знают, как позиционировать и визуализировать себя в заданном окне xy или проекции карты широты. Все, что вам нужно сделать, это предоставить данные о местоположении (x / y, широта / долгота) и информацию о чертеже (цвет, ширина линии), а остальная часть обрабатывается графикой.

Это должно быть легким и хорошим началом (мы увидим, например, как мы можем отображать данные из базы данных в следующем уроке), но, как вы могли заметить, интерактивности нет. Интерактивность демонстрируется InteractionLayer . Теперь вы должны иметь возможность заменить Basic слой на InteractionLayer в openmap.properties .

InteractionLayer демонстрирует, как взаимодействовать с вашими OMGraphic на карте, как заставить их изменять внешний вид с помощью событий мыши и предоставлять дополнительную информацию о себе. Этот слой основан на примере, продемонстрированном в BasicLayer .

Рисунок 4: Уровень взаимодействия

Рисунок 4: Уровень взаимодействия

Если вы запустите приложение, вы заметите, что, когда вы наводите курсор мыши на OMPoint, оно меняет цвет. Вы также можете щелкнуть по нему правой кнопкой мыши, чтобы открыть всплывающее меню. Мы будем использовать эту функцию для отображения свойств функции. Вы можете просмотреть com.bbn.openmap.layer.learn.InteractionLayer самостоятельно. Я просто OMGraphicHandlerLayer здесь несколько кратких рекомендаций о том, как добавить взаимодействия к вашему OMGraphicHandlerLayer . Не забудьте добавить эту строку в конструктор:

Листинг 4 — setMouseModeIDsForEvents ()

1
2
3
4
5
6
7
8
// Making the setting so this layer receives events from the
// SelectMouseMode, which has a modeID of "Gestures". Other
// IDs can be added as needed. You need to tell the layer which
// MouseMode it should listen to, so it can tell the MouseModes to send
// events to it.
// Instead of "Gestures", you can also use SelectMouseMode.modeID or
// OMMouseMode.modeID
setMouseModeIDsForEvents(new String[] { SelectMouseMode.modeID });  // "Gestures"        

Это фактически говорит вашему слою, что его функции должны реагировать на жесты мыши (например, наведение мыши). MouseEvent может управляться некоторыми компонентами OpenMap, направляя их на слои и на OMGraphic . MouseMode описывает, как MouseEvent и MouseMotionEvent интерпретируются и используются. MouseDelegator — это настоящий MouseListener и MouseMotionListener в MapBean . MouseDelegator управляет списком MouseMode и знает, какой из них является «активным» в любой момент времени. MouseDelegator также запрашивает у активных слоев свои MapMouseListener и добавляет те, которые заинтересованы в событиях из активного MouseMode качестве слушателей этого режима.

Когда MouseEvent запускается из MapBean, он проходит через MouseDelegator в активный MouseMode , где MouseMode начинает предоставлять MouseEvent своим MapMouseListener . Каждому слушателю предоставляется возможность использовать событие. MapMouseListener может воздействовать на событие и не использовать его, чтобы его можно было продолжать передавать другим слушателям.

MapMouseListener предоставляет массив String всех MouseMode ID от MouseMode ID он заинтересован в получении событий, а также имеет свои собственные методы, в MouseMotionEvent поступают MouseEvent и MouseMotionEvent . MapMouseListener может использовать эти события в сочетании с OMGraphicList , чтобы найти out, если события произошли на каком-либо OMGraphic , и ответить, если необходимо.

Есть несколько MouseModes которыми ваш слой может взаимодействовать. Поиск modeID в исходном коде или здесь возвращает следующие 8 режимов мыши (есть два дубликата):

  • DistanceMouseMode.modeID = "Distance"
  • DistQuickToolMouseMode.modeID = "Distance"
  • NavMouseMode.modeID = "Navigation"
  • NullMouseMode.modeID = "None"
  • OMDrawingToolMouseMode.modeID = "Drawing"
  • OMMouseMode.modeID = "Gestures"
  • PanMouseMode.modeID = "Pan"
  • RangeRighsMouseMode.modeID = "RangeRings"
  • SelectMouseMode.modeID = "Gestures"
  • ZoomMouseMode.modeID = "Zoom"

Не забудьте добавить что-то вроде следующего к вашим функциям при их создании, для визуального отображения, когда на них point.setSelectPaint(Color.yellow); курсор мыши: point.setSelectPaint(Color.yellow);

Вы можете переопределить следующие методы:

  • isSelectable() — Запрос о том, что OMGraphic можно выбрать. Вы должны вернуть true чтобы сделать его доступным для выбора.
  • isHighlightable() — Запрос, что OMGraphic может быть выделен, когда мышь перемещается над ним.
  • getInfoText() — отображать текст в строке состояния, когда указатель мыши находится над OMGraphic
  • getToolTipTextFor() — отображать всплывающую подсказку, когда мышь находится над OMGraphic

Например

Листинг 5 — методы взаимодействия

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
 * Query that an OMGraphic can be highlighted when the mouse moves over it.
 * If the answer is true, then highlight with this OMGraphics will be
 * called, and unhighlight will be called with the mouse is moved off of it.
 *
 * @see com.bbn.openmap.layer.OMGraphicHandlerLayer#highlight
 * @see com.bbn.openmap.layer.OMGraphicHandlerLayer#unhighlight
 */
public boolean isHighlightable(OMGraphic omg) {
    return true;
}
 
/**
 * Query that an OMGraphic is selectable. Examples of handing selection are
 * in the EditingLayer. The default OMGraphicHandlerLayer behavior is to add
 * the OMGraphic to an OMGraphicList called selectedList. If you aren't
 * going to be doing anything in particular with the selection, then return
 * false here to reduce the workload of the layer.
 *
 * @see com.bbn.openmap.layer.OMGraphicHandlerLayer#select
 * @see com.bbn.openmap.layer.OMGraphicHandlerLayer#deselect
 */
public boolean isSelectable(OMGraphic omg) {
    return true;
}

Если вы хотите отобразить всплывающее меню при щелчке правой кнопкой мыши на OMGraphic , переопределите следующий метод для возврата списка пунктов меню. В будущем уроке мы будем использовать этот метод для отображения свойств объекта из базы данных.

  • List getItemsForOMGraphicMenu(OMGraphic omg)

Если вы хотите отобразить всплывающее меню при щелчке правой кнопкой мыши в любом месте слоя, переопределите следующий метод, чтобы получить список пунктов меню:

  • List getItemsForMapMenu(MapMouseEvent me)

Надеюсь, это было довольно мило и не так сложно, однако вы не можете перемещать функции. Например, я хотел бы иметь возможность выбрать OMPoint и перетащить его на новую позицию. Чтобы добавить эту функциональность, нам нужно изучить некоторые слои, которые не перечислены в приведенных выше списках:

  • com.bbn.openmap.layer.DemoLayer
  • com.bbn.openmap.layer.DrawingToolLayer
  • com.bbn.openmap.layer.editor.EditorLayer

Попробуйте каждый из них. На самом деле мы видели DemoLayer в действии в предыдущем уроке, но мы не DemoLayer код. Итак, чтобы иметь возможность перетаскивать / изменять функции, вам необходимо:

  • Реализовать интерфейс DrawingToolRequestor
  • Определите и инициализируйте экземпляр DrawingTool в findAndInit()
  • Изменить isSelectable() , getInfoText() , getToolTipTextFor() , соответственно
  • Переопределите методы select() и drawingComplete() как показано в листинге 4

Листинг 6 — Как рисовать на карте

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
public class DemoLayer extends OMGraphicHandlerLayer implements DrawingToolRequestor {
 
   protected DrawingTool drawingTool;   
 
...
 
   public DrawingTool getDrawingTool() {
      // Usually set in the findAndInit() method.
      return drawingTool;
   }
 
   public void setDrawingTool(DrawingTool dt) {
      // Called by the findAndInit method.
      drawingTool = dt;
   }
 
   @Override
   public void findAndInit(Object someObj) {
      if (someObj instanceof DrawingTool) {
         setDrawingTool((DrawingTool) someObj);
      }
   }
 
   @Override
   public void findAndUndo(Object someObj) {
      if (someObj instanceof DrawingTool) {
         if (getDrawingTool() == (DrawingTool) someObj) {
            setDrawingTool(null);
         }
      }
   }
 
   @Override
   public boolean isSelectable(OMGraphic omg) {
      DrawingTool dt = getDrawingTool();
      return (dt != null && dt.canEdit(omg.getClass()));
   }
 
   @Override
   public String getInfoText(OMGraphic omg) {
      DrawingTool dt = getDrawingTool();
      return (dt != null && dt.canEdit(omg.getClass())) ? "Click to edit graphic." : null;
   }
 
   @Override
   public String getToolTipTextFor(OMGraphic omg) {
      Object tt = omg.getAttribute(OMGraphic.TOOLTIP);
      if (tt instanceof String) {
         return (String) tt;
      }
 
      String classname = omg.getClass().getName();
      int lio = classname.lastIndexOf('.');
      if (lio != -1) {
         classname = classname.substring(lio + 1);
      }
 
      return "Your Layer Object: " + classname;
   }
 
   @Override
   public void select(OMGraphicList list) {
      if (list != null && !list.isEmpty()) {
         OMGraphic omg = list.getOMGraphicAt(0);
         DrawingTool dt = getDrawingTool();
 
         if (dt != null && dt.canEdit(omg.getClass())) {
            dt.setBehaviorMask(OMDrawingTool.QUICK_CHANGE_BEHAVIOR_MASK);
            if (dt.edit(omg, this) == null) {
               // Shouldn't see this because we checked, but ...
               fireRequestInfoLine("Can't figure out how to modify this object.");
            }
         }
      }
   }
 
   @Override
   public void drawingComplete(OMGraphic omg, OMAction action) {
      if (!doAction(omg, action)) {
         // null OMGraphicList on failure, should only occur if
         // OMGraphic is added to layer before it's ever been
         // on the map.
         setList(new OMGraphicList());
         doAction(omg, action);
      }
      repaint();
   }
 
...
}

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

Когда вы нажимаете кнопку Drawing Tool Launcher , вы можете добавлять на слой множество типов графики, что может оказаться не тем, что вам нужно. Например, вы можете захотеть, чтобы ваш слой отображал только OMPoint s, и вы не хотите, чтобы пользователь мог добавлять, например, линии или круги, используя Drawing Tool . Это может быть легко сделано, если вы измените openmap.components оставив только omdrawingtool и ompointloader (или только типы загрузчиков OM, которые вы используете в своем приложении):

Листинг 7 — openmap.components, чтобы не отображать инструмент рисования (omdt)

1
openmap.components=menulist informationDelegator projFactory projectionstack toolBar zoompanel navpanel scalepanel projectionstacktool addlayer layersPanel overviewMapHandler layerHandler mouseDelegator projkeys coordFormatterHandler mouseModePanel mouseMode selectMouseMode navMouseMode distanceMouseMode panMouseMode omdrawingtool ompointloader

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

Виновником является OMDrawingTool . Поскольку OpenMap является проектом с открытым исходным кодом, рекомендуется прочитать код вышеуказанного класса ( com.bbn.openmap.tools.drawing.OMDrawingTool ). Собственно, в методе select() вы увидите строку:

1
dt.setBehaviorMask(OMDrawingTool.QUICK_CHANGE_BEHAVIOR_MASK);

OMDrawingTool определяет несколько масок поведения:

  • SHOW_GUI_BEHAVIOR_MASK
  • GUI_VIA_POPUP_BEHAVIOR_MASK
  • USE_POPUP_BEHAVIOR_MASK
  • ALT_POPUP_BEHAVIOR_MASK
  • PASSIVE_MOUSE_EVENT_BEHAVIOR_MASK
  • DEACTIVATE_ASAP_BEHAVIOR_MASK
  • DEFAULT_BEHAVIOR_MASK
  • QUICK_CHANGE_BEHAVIOR_MASK

Вы можете попробовать их все, чтобы увидеть, как ведет себя слой. К сожалению, ни один из них не покрывает наши потребности. Если всплывающее окно (или наше всплывающее окно) не появляется, функция не может быть перетащена в другое место; если появляется всплывающее окно, это одно из OMDrawingTool . Итак, хак. Мы создадим наш собственный OMDrawingTool :

Листинг 8 — Класс MyDrawingTool

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
public class MyDrawingTool extends OMDrawingTool {
 
    public MyDrawingTool() {
        super();
        setBehaviorMask(OMDrawingTool.QUICK_CHANGE_BEHAVIOR_MASK);
    }
     
    @Override
    public JPopupMenu createPopupMenu() {
        JPopupMenu popup =  super.createPopupMenu();
        popup.removeAll();
        popup.add(new JMenuItem("Which"));
        popup.add(new JMenuItem("Why"));
        return popup;
    }
}

Вы можете пойти еще дальше, добавив методы set, чтобы установить список JMenuItem созданный методом getItemsForOMGraphicMenu() , но я оставляю это как упражнение для вас. Нам нужно сделать еще одну вещь:

Листинг 9 — openmap.properties для отображения нашего инструмента рисования

1
2
omdrawingtool.class=openmap.MyDrawingTool
#omdrawingtool.class=com.bbn.openmap.tools.drawing.OMDrawingTool

С этим изменением вы можете удалить строку, которая устанавливает маску поведения в методе select() вашего слоя.

Слои OpenMap также поддерживают анимацию. Замените предыдущий слой на SimpleAnimationLayer в openmap.properties . При повторном запуске приложения вы видите пустую карту. Нажмите на кнопку слоев и выберите свойства AnimationLayer (см. Рисунок 5 ). В появившемся диалоговом окне добавьте спрайты, нажав соответствующую кнопку, и, когда вы будете довольны, установите флажок « Таймер запуска», чтобы увидеть их перемещение. Вы можете настроить ползунок интервала таймера, чтобы они двигались быстрее или медленнее.

Рисунок 5: Анимационный слой

Рисунок 5: Анимационный слой

Все ранее упомянутые слои расширяют OMGraphicHandlerLayer . Но вы можете обойтись без этого. Например, взгляните на HelloWorldLayer который переопределяет Layer напрямую. Его createGraphics() создает объекты и добавляет их в переданный OMGraphicList .

TestLayer проверить другие слои, упомянутые в начале этой статьи, такие как TestLayer , GeoTestLayer и т. Д.

Чтобы кнопка « Свойства» была включена в диалоговом окне «Слои» и что-то отображалось, необходимо переопределить метод getGUI() . Смотрите, например, TestLayer или SimpleAnimationLayer .

3. Вывод

Этот урок был посвящен слоям OpenMap. Мы начали с простого BasicLayer , который отображает статические данные, затем добавили взаимодействие с InteractionLayer , продемонстрировали, как перемещать объекты в новые местоположения на карте или изменили геометрию объектов с помощью мыши, и продолжили с AnimationLayer чтобы продемонстрировать, как анимировать объекты слоя , Мы не покрывали все. Несмотря на то, что мы видели, как добавлять и управлять функциями, мы еще не говорили о проекциях. В следующем уроке мы создадим наше первое трехуровневое приложение, в котором мы увидим, как отображать данные из базы данных на карте.