2 votos

SLD: La función Categorizar no funciona con la etiqueta <TextSymbolizer>

Estoy trabajando en Java con la biblioteca GeoTools en formato de estilo sld. Me encontré con un problema que no puedo resolver durante 3 días ya.

Mi tarea consiste en representar el tamaño de la fuente de las etiquetas según la escala actual. De acuerdo con documentos del geoservidor y la solución común Intento trabajar con la función de categorización.

 <CssParameter name="font-size">
        <ogc:Function name="Categorize">
          <!-- Value to transform -->
          <ogc:Function name="env">
            <ogc:Literal>wms_scale_denominator</ogc:Literal>
          </ogc:Function>
          <!-- Output values and thresholds -->
          <!-- Ranges: -->
          <!-- [scale <= 300, font 12] -->
          <!-- [scale 300 - 2500, font 10] -->
          <!-- [scale > 2500, font 8] -->
          <ogc:Literal>12</ogc:Literal>
          <ogc:Literal>300</ogc:Literal>
          <ogc:Literal>10</ogc:Literal>
          <ogc:Literal>2500</ogc:Literal>
          <ogc:Literal>8</ogc:Literal>
        </ogc:Function>
      </CssParameter>

Pero me he enfrentado a los problemas:

  • Para la representación de las etiquetas sólo utiliza el primer parámetro de tamaño de fuente e ignora el segundo y el tercero.
  • Sólo renderiza las etiquetas a su propia escala, sin importar lo que ponga en el primer argumento de escala y en el segundo. Supongo que se renderizan las etiquetas cuando se renderizan los polígonos propios.

aquí está mi código sld:

<CssParameter xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/CssParameter.xsd" xmlns:se="http://www.opengis.net/se">

edificio-polígono edificio-polígono

    <se:Rule>
      <se:Name>Single symbol</se:Name>
      <se:MinScaleDenominator>0</se:MinScaleDenominator>
      <se:MaxScaleDenominator>100000</se:MaxScaleDenominator>
      <se:PolygonSymbolizer>
        <se:Fill>
          <se:CssParameter name="fill">#cbcbc9</se:CssParameter>
          <se:CssParameter name="fill-opacity">0.79</se:CssParameter>
        </se:Fill>
        <se:Stroke>
          <se:CssParameter name="stroke">#cbcbc9</se:CssParameter>
          <se:CssParameter name="stroke-linejoin">bevel</se:CssParameter>
        </se:Stroke>
      </se:PolygonSymbolizer>

      <TextSymbolizer>      

        <Geometry>
            <ogc:Function name="centroid">
                <ogc:PropertyName>the_geom</ogc:PropertyName>
            </ogc:Function>
        </Geometry>

        <Label>
            <ogc:PropertyName>A_HSNMBR</ogc:PropertyName>
        </Label>

        <Font>
            <CssParameter name="font-family">Arial</CssParameter>
            <CssParameter name="font-size">                 

                <ogc:Function name="Categorize">                                
                    <ogc:Function name="env">
                        <ogc:Literal>wms_scale_denominator</ogc:Literal>
                    </ogc:Function>                     

                    <ogc:Literal>10</ogc:Literal>
                    <ogc:Literal>300</ogc:Literal>                      
                    <ogc:Literal>6</ogc:Literal>
                    <ogc:Literal>2500</ogc:Literal>                     
                    <ogc:Literal>1</ogc:Literal>                        

                </ogc:Function>
            </CssParameter>        
            <CssParameter name="font-style">normal</CssParameter>
            <CssParameter name="font-weight">normal</CssParameter>
        </Font>     
        <LabelPlacement>           
            <LinePlacement>             
                <PointPlacement>
                    <AnchorPoint>
                        <AnchorPointX>0.5</AnchorPointX>
                        <AnchorPointY>0.5</AnchorPointY>
                    </AnchorPoint>
                </PointPlacement>
            </LinePlacement>
        </LabelPlacement>                       
        <Fill>
            <CssParameter name="fill">#2a2a35</CssParameter>
        </Fill>     
        <!-- <VendorOption name="polygonAlign">ortho</VendorOption> 
             <VendorOption name="autoWrap">60</VendorOption> -->
      </TextSymbolizer>       
    </se:Rule>

  </se:FeatureTypeStyle>
</UserStyle>

Y aquí está mi código Java:

package TestGeoToolsMvn;

import java.awt.Rectangle;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.List;

import org.geotools.data.CachingFeatureSource;
import org.geotools.data.FileDataStore;
import org.geotools.data.FileDataStoreFinder;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.geometry.DirectPosition2D;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.map.FeatureLayer;
import org.geotools.map.Layer;
import org.geotools.map.MapContent;
import org.geotools.renderer.lite.StreamingRenderer;
import org.geotools.styling.SLD;
import org.geotools.styling.SLDParser;
import org.geotools.styling.Style;
import org.geotools.styling.StyleFactory;
import org.geotools.swing.dialog.JExceptionReporter;
import org.jfree.fx.FXGraphics2D;

import javafx.scene.input.*;
import javafx.application.Platform;
import javafx.concurrent.ScheduledService;
import javafx.concurrent.Task;
import javafx.event.EventHandler;
import javafx.scene.Node;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.util.Duration;

public class MapCanvas {
    private Canvas canvas;
    private MapContent map;
    private GraphicsContext graphicsContext;
    static StyleFactory styleFactory = CommonFactoryFinder.getStyleFactory();

    private boolean repaint = true;
    private double baseDrageX;
    private double baseDrageY;
    private static final double PAINT_HZ = 50.0;

    //============================= CONSTANT ===============================
    final int INDEX_FROM = 1; //inex for hide and show layers methods
    final String HOME_DIR_1 = "src\\main\\resources\\";

    java.awt.Color colorBackground = new java.awt.Color(250, 250, 250);

    public MapCanvas(int width, int height) {

        canvas = new Canvas(width, height);
        graphicsContext = canvas.getGraphicsContext2D();
        map = new MapContent();
        map.setTitle("Quickstart");

        initLayer("testGeoToolsMvn\\110m_cultural\\data\\boundary-polygon.shp");
        initLayer("testGeoToolsMvn\\110m_cultural\\data\\landuse-polygon.shp");
        initLayer("testGeoToolsMvn\\110m_cultural\\data\\settlement-polygon.shp");

        initLayer("testGeoToolsMvn\\110m_cultural\\data\\building-polygon.shp");
        initLayer("testGeoToolsMvn\\110m_cultural\\data\\railway-platform-polygon.shp");
        initLayer("testGeoToolsMvn\\110m_cultural\\data\\vegetation-polygon.shp");
        initLayer("testGeoToolsMvn\\110m_cultural\\data\\water-polygon.shp");
        initLayer("testGeoToolsMvn\\110m_cultural\\data\\water-line.shp");

        initLayer("testGeoToolsMvn\\110m_cultural\\data\\railway-line.shp");
        initLayer("testGeoToolsMvn\\110m_cultural\\data\\highway-line.shp");

        drawMap(graphicsContext);
        initEvent();
        initPaintThread(); 
    }

    public Node getCanvas() {
        return canvas;
    }

    private void initLayer(String pathToShp) {
        try {
            FileDataStore store = FileDataStoreFinder.getDataStore(this.getClass().getClassLoader().getResource(pathToShp));
            SimpleFeatureSource featureSource = store.getFeatureSource();

            ((ShapefileDataStore) store).setCharset(Charset.defaultCharset());
            Style style = createFromSLD(pathToShp);
            FeatureLayer layer = new FeatureLayer(featureSource, style);
            System.out.println(" :    " + pathToShp);
            System.out.println(" :  : " + pathToShp);

            map.getViewport().setScreenArea(new Rectangle((int) canvas.getWidth(), (int) canvas.getHeight()));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void drawMap(GraphicsContext gc) {
        if (repaint) {
            repaint = false;
            StreamingRenderer draw = new StreamingRenderer();
            draw.setMapContent(map);
            FXGraphics2D graphics = new FXGraphics2D(gc);
            graphics.setBackground(colorBackground);
            graphics.clearRect(0, 0, (int) canvas.getWidth(), (int) canvas.getHeight());
            Rectangle rectangle = new Rectangle((int) canvas.getWidth(), (int) canvas.getHeight());

            draw.paint(graphics, rectangle, map.getViewport().getBounds());
        }
        else {return;}
    }

    private void initEvent() {
        canvas.addEventHandler(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() {

            @Override
            public void handle(MouseEvent e) {
                baseDrageX = e.getSceneX();
                baseDrageY = e.getSceneY();
                e.consume();
            }
        });

        canvas.addEventFilter(MouseEvent.DRAG_DETECTED, e -> {
            canvas.startFullDrag();
            System.out.println("Drag starts");
        });

        canvas.addEventHandler(MouseDragEvent.MOUSE_DRAG_OVER, new EventHandler<MouseDragEvent>() {
            @Override
            public void handle(MouseDragEvent e) {
                System.out.println("Dragging");
                hideLayers(INDEX_FROM); //Hide layers for performance achievments

                double difX = e.getSceneX() - baseDrageX;
                double difY = e.getSceneY() - baseDrageY;
                baseDrageX = e.getSceneX();
                baseDrageY = e.getSceneY();
                DirectPosition2D newPos = new DirectPosition2D(difX, difY);
                DirectPosition2D result = new DirectPosition2D();
                map.getViewport().getScreenToWorld().transform(newPos, result);
                ReferencedEnvelope env = new ReferencedEnvelope(map.getViewport().getBounds());
                env.translate(env.getMinimum(0) - result.x, env.getMaximum(1) - result.y);
                doSetDisplayArea(env);
                e.consume();
            }
        });

        canvas.addEventHandler(MouseDragEvent.MOUSE_DRAG_RELEASED, new EventHandler<MouseDragEvent>() {
            @Override
            public void handle(MouseDragEvent e) {
                System.out.println("Realesed");
                showLayers(INDEX_FROM, map.getViewport().getBounds()); //Show layers for performance achievments

                e.consume();
            }
        });

        /*
         * double clicks to restore to original map
         */
        canvas.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent t) {
                if (t.getClickCount() > 1) {
                    doSetDisplayArea(map.getMaxBounds());
                }
                t.consume();
            }
        });
        /*
         * scroll for zoom in and out
         */
        canvas.addEventHandler(ScrollEvent.SCROLL, new EventHandler<ScrollEvent>() {
            private int scrollCounter = 0; //counter for creating self-made SCROLL_FINISHED event

            @Override
            public void handle(ScrollEvent e) {
                System.out.println("Scrolled");
                hideLayers(INDEX_FROM); //Hide layers for performance achievments

                ReferencedEnvelope envelope = map.getViewport().getBounds();
                double percent = (e.getDeltaY() / canvas.getWidth()) * 4;
                double width = envelope.getWidth();
                double height = envelope.getHeight();
                double deltaW = width * percent;
                double deltaH = height * percent;
                envelope.expandBy(deltaW, deltaH);
                doSetDisplayArea(envelope);
                e.consume();

                scrollCounter ++;

                Thread th = new Thread(() -> {
                    try {
                        Thread.sleep(1000);
                        Platform.runLater(() -> {
                            if(scrollCounter == 1) {
                                System.out.println("Scroll ended!");
                                showLayers(INDEX_FROM, envelope); //Show layers for performance achievments
                            }
                            scrollCounter--;

                        });
                    } catch (Exception e1) {
                        e1.printStackTrace();
                    }
                });
                th.setDaemon(true);
                th.start();

            }
        });
    }

    private void initPaintThread() {
        ScheduledService<Boolean> svc = new ScheduledService<Boolean>() {
            protected Task<Boolean> createTask() {
                return new Task<Boolean>() {
                    protected Boolean call() {
                        Platform.runLater(() -> {
                            drawMap(graphicsContext);
                        });
                        return true;
                    }
                };
            }
        };
        svc.setPeriod(Duration.millis(1000.0 / PAINT_HZ));
        svc.start();
    }

    public void hideLayers(int indexFrom) {
        //Hide layers for performance achievments
        List<Layer> layers;
        layers = map.layers();
        for (indexFrom = indexFrom; indexFrom < layers.size(); indexFrom++){
            layers.get(indexFrom).setVisible(false);
            Layer l = layers.get(indexFrom);
            System.out.println(" :   - " + l.toString());
        }
    }

    public void showLayers(int indexFrom, ReferencedEnvelope envelope) {
        //Show layers for performance achievments
        List<Layer> layers;
        layers = map.layers();
        for (indexFrom = indexFrom; indexFrom < layers.size(); indexFrom++){
            layers.get(indexFrom).setVisible(true);
            doSetDisplayArea(envelope);
            Layer l = layers.get(indexFrom);
            System.out.println(" :   - " + l.toString());
        }
    }

    protected void doSetDisplayArea(ReferencedEnvelope envelope) {
        map.getViewport().setBounds(envelope);
        repaint = true;
    }

    /**
     * Create a Style object from a definition in a SLD document
     */
    private Style createFromSLD(String pathToSLD) {
        try {
            pathToSLD = HOME_DIR_1 + pathToSLD.replaceAll(".shp",".sld");
            SLDParser stylereader = new SLDParser(styleFactory, pathToSLD);
            //Style[] style = stylereader.readXML();
            Style[] style = stylereader.readXML();
            return style[0];

        } catch (Exception e) {
            JExceptionReporter.showDialog(e, " :      ");
        }

        return null;
    }
}

enter image description here

1voto

user2831 Puntos 11

Las funciones están soportadas en todos los CSSParameter (por especificación), pero nuestro código no funciona porque el wms_scale_denominator es añadida por algún código de GeoServer en la maquinaria de WMS, y por lo tanto no está disponible en su cliente independiente de GeoTools.

Como referencia, aquí está el código de GeoServer responsable de la creación de wms_scale_denominator : https://github.com/geoserver/geoserver/blob/6058e38a0c74247ee6fea3db81c3aecbca1f40d2/src/wms/src/main/java/org/geoserver/wms/RenderingVariables.java#L21

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X