ordering.html 8.69 KB
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <link rel="stylesheet" href="../theme/default/style.css" type="text/css" />
    <link rel="stylesheet" href="style.css" type="text/css" />
    <style type="text/css">
        .smallmap {
            width: 300px;
        }
        
        .docs {
            padding: 0px 5px;
        }
        
        td {
            vertical-align: top;
        }
        
    </style>
    <script src="../lib/OpenLayers.js" type="text/javascript"></script>
    <script type="text/javascript">
        
        var GOLD_Z_INDEX = 15;
        var FIRST_RED_Z_INDEX = 10;
        var SECOND_RED_Z_INDEX = 11;
        
        var RADIUS_FROM_CENTER = 40;
        var POINT_DISTANCE = 10;
            
        function initYOrderMap() {
            var map = new OpenLayers.Map("yorder");
            
            var layer = new OpenLayers.Layer.Vector(
                "Y-Order",
                {
                    styleMap: new OpenLayers.StyleMap({
                        externalGraphic: "../img/marker-gold.png",
                        pointRadius: 10,
                        graphicZIndex: GOLD_Z_INDEX
                    }),
                    isBaseLayer: true,
                    rendererOptions: {yOrdering: true}
                }
            );
            
            map.addLayers([layer]);
            map.zoomToMaxExtent();
            
            // Add features to the layers to show off z-index/y-ordering.
            // We do this after adding the layer so we can work in pixels.
            var center = map.getViewPortPxFromLonLat(map.getCenter());
            
            var top = new OpenLayers.Pixel(center.x, center.y - RADIUS_FROM_CENTER);
            var bottom = new OpenLayers.Pixel(center.x, center.y + RADIUS_FROM_CENTER);
            var left = new OpenLayers.Pixel(center.x - RADIUS_FROM_CENTER, center.y - POINT_DISTANCE / 2);
            var right = new OpenLayers.Pixel(center.x + RADIUS_FROM_CENTER, center.y - POINT_DISTANCE / 2);
            
            // Add the ordering features. These are the gold ones that all have the same z-index
            // and succomb to y-ordering.
            var orderingFeatures = [];
            // Note: We use > here on purpose (instead of >= ), as well as subtracting the
            // the POINT_DISTANCE in the beginning of the loop (as opposed to the end).
            // This is purely for symmetry. Also note that the gold features are drawn
            // from bottom to top so as to quickly signal whether or not y-ordering is working.
            while (bottom.y > top.y) {
                bottom.y -= POINT_DISTANCE;
                var lonLat = map.getLonLatFromViewPortPx(bottom);
                orderingFeatures.push(
                    new OpenLayers.Feature.Vector(
                        new OpenLayers.Geometry.Point(lonLat.lon, lonLat.lat)
                    )
                );
            }
          
            layer.addFeatures(orderingFeatures);
            
            // Add the z-index features. Technically, these features succomb to y-ordering
            // as well; however, since they have different z-indexes, the z-indexes take 
            // precedence.
            var indexFeatures = [];
            var useFirst = true;
            while (left.x <= right.x) {
                var lonLat = map.getLonLatFromViewPortPx(left);
                var point = new OpenLayers.Feature.Vector(
                    new OpenLayers.Geometry.Point(lonLat.lon, lonLat.lat)
                );
                
                // This is where the magic happens. We override the style on the layer
                // to give our own style with alternativing z-indexes.
                point.style = {
                    graphicZIndex: useFirst ? FIRST_RED_Z_INDEX : SECOND_RED_Z_INDEX,
                    externalGraphic: "../img/marker.png",
                    pointRadius: 10
                }
                
                indexFeatures.push(
                    point
                );
                
                left.x += POINT_DISTANCE;
                useFirst = !useFirst;
            }
            
            layer.addFeatures(indexFeatures);
        }
        
        function initDrawingOrderMap() {
            var map = new OpenLayers.Map("drawingorder");
            
            var layer = new OpenLayers.Layer.Vector(
                "Drawing Order",
                {
                    // Note there's no z-index set, and yOrdering is left
                    // to its default.
                    styleMap: new OpenLayers.StyleMap({
                        externalGraphic: "../img/marker-green.png",
                        pointRadius: 10
                    }),
                    isBaseLayer: true
                }
            );
            
            map.addLayers([layer]);
            map.zoomToMaxExtent();
            
            // Add features to the layers to show off z-index/y-ordering.
            // We do this after adding the layer so we can work in pixels.
            var center = map.getViewPortPxFromLonLat(map.getCenter());
            
            var top = new OpenLayers.Pixel(center.x, center.y - RADIUS_FROM_CENTER);
            var bottom = new OpenLayers.Pixel(center.x, center.y + RADIUS_FROM_CENTER);
            var left = new OpenLayers.Pixel(center.x - RADIUS_FROM_CENTER, center.y);
            var right = new OpenLayers.Pixel(center.x + RADIUS_FROM_CENTER, center.y);
            
            // Add the ordering features. These are the gold ones that all have the same z-index
            // and succomb to y-ordering.
            var orderingFeatures = [];
            while (bottom.y > top.y && left.x < right.x) {
                var bottomLonLat = map.getLonLatFromViewPortPx(bottom);
                var leftLonLat = map.getLonLatFromViewPortPx(left);
                orderingFeatures.push(
                    new OpenLayers.Feature.Vector(
                        new OpenLayers.Geometry.Point(leftLonLat.lon, bottomLonLat.lat)
                    )
                );
                bottom.y -= POINT_DISTANCE / 2; // Divide by 2 for better visual.
                left.x += POINT_DISTANCE / 2;
            }
          
            layer.addFeatures(orderingFeatures);
        }

        function init(){
            initYOrderMap();
            initDrawingOrderMap();
        };
        
    </script>
  </head>
  <body onload="init()">
        <h1 id="title">Z-Index/Y-Order Example</h1>

        <div id="tags">
        </div>

        <p id="shortdesc">
           This example shows the use of z-indexing and y-ordering of external graphics. Zoom in and out to see this behavior.
        </p>

        <h3>Z-Index (with Y-Ordering enabled)</h3>
        <table>
            <tr>
                <td>
                    <div id="yorder" class="smallmap"></div>
                </td>
                <td>
                    <div class="docs">
                        In this map, the gold features all have the same z-index, and the red features have alternating z-indeces. The gold features' z-index is greater than the red features' z-indeces, which is why gold features look to be drawn on top of the red features. Since each gold feature has the same z-index, gold features succomb to y-ordering: this is where features that seem closest to the viewer (lower lattitude) show up above those that seem farther away (higher lattitude).
                        <br><br>
                        All vector layers have z-indexing enabled by default, but are not enabled with y-ordering. You can enable y-ordering by passing the parameter <i>yOrdering: true</i> in the vector layer's options hash. For all configurations, if features have the same z-index -- and if y-ordering is enabled: the same lattitude -- those features will succomb to drawing order, where the last feature to be drawn will appear above the rest.
                    </div>
                </td>
            </tr>
        </table>
        <br>
        <h3>Drawing Order (no Z-Indexes set, and Y-Ordering disabled)</h3>
        <table>
            <tr>
                <td>
                    <div id="drawingorder" class="smallmap"></div>
                </td>
                <td>
                    <div class="docs">
                        In this map, features are not given z-indexes, and the layer's <i>yOrdering</i> parameter is set to the default (false). This configuration makes features succomb to drawing order instead of z-index order or y-order.
                        <br><br>
                        The features in this map were drawn from left to right and bottom to top, diagonally, to show that y-ordering is not enabled.
                    </div>
                </td>
            </tr>
        </table>
        
        
    </body>
</html>