|
| 1 | +Take a look at the introductory doc comments in MapExtentLayer.js, MapTileLayer.js and |
| 2 | +MapFeatureLayer.js which illustrate the expected custom elements model that will be |
| 3 | +implemented by the target code state. |
| 4 | + |
| 5 | +Background |
| 6 | + |
| 7 | +In this branch, MapExtentLayer and MapTileLayer have been refactored to become member layers |
| 8 | +in the MapLayer LayerGroup, although MapExtentLayer has some differences because it |
| 9 | +implements the <map-extent> element which has the checked attribute controlling |
| 10 | +how it is added or removed from the map, hence the map-extent._handleChange event handling |
| 11 | +method which is tied to the checked attribute, and associated to the <input type="checkbox"> |
| 12 | +representation of the <map-extent> in the layer control (as a "sub-layer"). |
| 13 | +The MapExtentLayer is added/removed to/from the map-layer._layer (instance of |
| 14 | +MapLayer) LayerGroup by the map-extent._handleChange method. This makes sense |
| 15 | +because while the map-layer._layer may be on the map (added to the Leaflet map), |
| 16 | +the map-extent._extentLayer may not be, due to the map-extent.checked (absent/false value) |
| 17 | +attribute. In other words, the _extentLayer itself will or will not be a member of |
| 18 | +the map-layer._layer._layers (LayerGroup) collection, according to the associated |
| 19 | +<map-layer>.checked value. |
| 20 | + |
| 21 | +The MapTileLayer instance(s) associated to sequences of <map-tile> elements in the |
| 22 | +content of the MapLayer is / are always members of the <map-layer>._layer._layers |
| 23 | +(LayerGroup instance), because the <map-tile> element isn't controlled by a checked |
| 24 | +attribute, and individual <map-tile>s are rendered on demand according to their |
| 25 | +row,column and zoom, due to being rendered "on demand" by the MapTileLayer (GridLayer) |
| 26 | +internal tile management. The MapTileLayer in which a <map-tile> is a member is |
| 27 | +always included in the <map-layer>._layer._layers (MapLayer LayerGroup instance), |
| 28 | +and therefore is on the map or not on the map according to the <map-layer>.checked value. |
| 29 | + |
| 30 | +The current objective is to refactor FeatureLayer as MapFeatureLayer, map-feature.js |
| 31 | +and MapFeature.js to work in all the contexts that FeatureLayer currently works, |
| 32 | +which are about four in number, discussed below (in preparation, FeatureLayer.js has been copied and name-only refactored to the MapFeatureLayer.js file, including the aforementioned |
| 33 | +new header comment). |
| 34 | + |
| 35 | +The four contexts in which MapFeature currently works include: |
| 36 | + |
| 37 | + 1. "static" inline <map-feature> child elements of the light DOM <map-layer> node, |
| 38 | + which are potentially siblings of <map-tile> and <map-extent> elements, (among others |
| 39 | + but those are the elements that are renderable as Leaflet layers or parts of |
| 40 | + Leaflet layers, OR "static" remote <map-feature> children fetched from the <map-layer src> |
| 41 | + and re-parented to the shadow root of <map-layer>. |
| 42 | + 2. <map-feature> elements returned by <map-link rel="query"> elements that are part |
| 43 | + of <map-extent> contents. The popups created by these features are tricky and |
| 44 | + have popup navigation button controls in the popup content, created by code |
| 45 | + in this repository. |
| 46 | + 3. <map-feature> elements that are found in fetched text/mapml documents that are |
| 47 | + fetched, rendered and removed as part of the map processing handled by |
| 48 | + <map-extent> child <map-link rel="features"> and TemplatedFeaturesOrTilesLayer. |
| 49 | + Typically such features have interactive behaviour (popups) and navigation buttons. |
| 50 | + 4. <map-feature> elements that are fetched and rendered as part of the processing |
| 51 | + of <map-extent> child <map-link rel="tile" type="text/mapml">. These features |
| 52 | + are not interactive; they are rendered according to provided styles, |
| 53 | + but they don't have popups, relying instead on query links per 2, above. |
| 54 | + |
| 55 | +In addition, FeatureLayer relies on src/features/featureRenderer.js, geometry.js and |
| 56 | +path.js. I would like to simplify or eliminate these classes, but I don't understand them. |
| 57 | +I will need to discuss any changes before doing them in order to understand the |
| 58 | +impact of such changes. |
| 59 | + |
| 60 | +I want to apply a similar architecture to <map-feature> / MapFeatureLayer.js as |
| 61 | +I have done to <map-tile> / MapTileLayer. and <map-extent> / MapExtentLayer.js, |
| 62 | +but this step is more complex and has greater ramifications on testing especially, |
| 63 | +because the rendering of features is done via the custom featureRenderer.js, path.js |
| 64 | +and geometry.js (I believe), whereas tile rendering is well managed by the MapTileLayer |
| 65 | +GridLayer subclass. |
| 66 | + |
| 67 | +Background about the numbered contexts above: |
| 68 | + |
| 69 | +1. "static" inline features. The code in the _initialize processFeatures function will be the first |
| 70 | +code to be deleted. That code creates a single MapLayer._mapmlvectors member variable |
| 71 | +but that is simplistic: each *set* of adjacent <map-feature> elements in the |
| 72 | +inline or remote content should create a single MapFeatureLayer wherein the first |
| 73 | +such <map-feature> creates the MapFeatureLayer (a Leaflet FeatureGroup), and |
| 74 | +subsequent *adjacent* <map-feature> elements are added to that MapFeatureLayer |
| 75 | +FeatureGroup by the <map-feature> connectedCallback chain, much as is already done |
| 76 | +by the <map-tile> connectedCallback (in which case, the collection layer is a |
| 77 | +MapTileLayer GridLayer). On the other hand, <map-feature> elements which add themselves |
| 78 | +to the map-layer._layer LayerGroup aren't removed unless and until the <map-feature> |
| 79 | +element itself is removed - these <map-feature> elements are what is currently |
| 80 | +handled by MapLayer._initialize.processFeatures, so this is the first bit related |
| 81 | +to MapFeatureLayer to get refactored. |
| 82 | + |
| 83 | +The <map-layer> implementation in layer.js also defines mutation observers which |
| 84 | +watch the light DOM children or shadow root children (depending on presence / absence |
| 85 | +of <map-layer src> attribute). One of the tasks of mutation observer is to obtain |
| 86 | +invoke _addFeatureToMapMLVectors for <map-feature> additions. While it may be a |
| 87 | +good architecture to have _addFeatureToMapMLVectors invoked, its behaviour should |
| 88 | +be limited to recalculating or ensuring that the <map-layer>.extent is recalculated |
| 89 | +the next time it is requested, at least. I think that it's desirable that each |
| 90 | +<map-feature> detect any previous sibling <map-feature> elements (in a sequence |
| 91 | +of such features) and use / add itself that element's _layer MapFeatureLayer (FeatureGroup) |
| 92 | +instance, in a similar (not identical) manner to how <map-tile> adds itself to its previous |
| 93 | +sibling's MapTileLayer GridLayer. This behaviour is implemented by <map-feature> |
| 94 | +when being added to the shadow root of a <map-link> element, with the |
| 95 | +TemplatedFeaturesOrTilesLayer being the analog of MapLayer in this case. |
| 96 | + |
0 commit comments