<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">El 1 de junio de 2017, 20:09, Alex Irmel Oviedo Solis <span dir="ltr">&lt;<a href="mailto:alleinerwolf@gmail.com" target="_blank">alleinerwolf@gmail.com</a>&gt;</span> escribió:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>Buenas tardes, continuo modificando la extension LandRegistryViewer y necesito obtener registros asociados a un poligono pero de la forma actual de la extension se muestran más resultados de los que deberian y no entiendo del todo el codigo para modificar ese comportamiento.<br><br></div><div>Por lo poco que entiendo, la clase IntersectsEvaluator que extiende a AbstractEvaluator es la que realiza la consulta de intersección de un punto con los poligonos y que al parecer tiene un buffer alto y por esto intersecta a más de un poligono y lo que requiero es que el buffer sea minimo para obtener un solo poligono.<br><br></div><div>Espero que me puedan dar una ayudita en este problema, gracias de antemano. Saludos<br></div></div>
<br>______________________________<wbr>_________________<br>
gvSIG_desarrolladores mailing list<br>
<a href="mailto:gvSIG_desarrolladores@listserv.gva.es">gvSIG_desarrolladores@<wbr>listserv.gva.es</a><br>
Para ver histórico de mensajes, editar sus preferencias de usuario o darse de baja en esta lista, acuda a la siguiente dirección: <a href="https://listserv.gva.es/cgi-bin/mailman/listinfo/gvsig_desarrolladores" rel="noreferrer" target="_blank">https://listserv.gva.es/cgi-<wbr>bin/mailman/listinfo/gvsig_<wbr>desarrolladores</a><br>
<br></blockquote></div><br><br><br>Hola Alex,<br>no entiendo cual es tu problema, te voy contando a <br>ver si te sirve algo de lo que te cuento y con todo ya ves <br>de concretar un poco mas la duda.<br><br>La forma de recuperar registros de una fuente de datos <br>seria algo como:<br><br>  FeatureStore store = ... ;<br>  FeatureSet set = null;<br>  DisposableIterator it = null;<br>  <br>  try {<br>    set = store.getFeatureStore();<br>    it = set.fastIterator();<br>    while( it.hasNext() ) {<br>      Feature f = (Feature) it.next();<br>      <br>      ... hacer lo que toque con la feature ...<br>      <br>    }<br>  } catch(Throwable th) {<br>    ... tratamiento de errores ...<br>  } finally {<br>    DisposeUtils.disposeQuietly(it);<br>    DisposeUtils.disposeQuietly(set);<br>  }<br><br>Cuando sea posible recomiendo usar un visitor en lugar de iterar sobre<br>los registros pero entiendo que sea mas facil entender la version con<br>el iterador. De todos modos dejo aqui la version del visitor.<br><br>  FeatureStore store = ... ;<br><br>  FeatureSet set = null;<br>  DisposableIterator it = null;<br>  <br>  try {<br>    set = store.getFeatureStore();<br>    set.accept(new Visitor() {<br>      public void visit(Object obj) throws VisitCanceledException, BaseException {<br>        Feature f = (Feature) obj;<br>        <br>        ... hacer lo que toque con la feature ...<br>      }<br>    );<br>    <br>  } catch(Throwable th) {<br>    ... tratamiento de errores ...<br>  } finally {<br>    DisposeUtils.disposeQuietly(set);<br>  }<br><br>Bueno, elejimos una u otra forma para recorrer las features de una fuente<br>de datos.<br><br>Ahora bien asi, nos recorremos todas las features de esa fuente de datos.<br>¿ Y si solo queremos unas pocas ?<br>Si solo queremos las features cuya geometria intersecte con un poligono dado.<br><br>Invocaremos al metodo getFeatureStore, pero pasandole la condicion de filtrado <br>que deseemos. Vamos a ver como hacerlo.<br><br>  <br>    FeatureQuery query = store.createFeatureQuery();<br>    Evaluator filtro = MyIntersectsEvaluator(...);<br>    query.setFilter(filtro);<br>    set = store.getFeatureStore(query);<br><br>De esta forma obtendriamos las features que cumplen el filtro especificado.<br>¿ Y que es ese filtro ?<br><br>El filtro es una instancia de Evaluator.<br>Simplificando la explicacion, la libreria de acceso a datos lo que hace es,<br>recoger todas las features y para cada una de ellas invoca al metodo<br>evaluate del filtro. Si este metodo devuelbe true, esa feature es incluida en <br>el resultado de la consulta, si no, no es incluida.<br><br>El metodo evaluate recive los datos de la feature para que puedas realizar con <br>ellos la operacion que necesites. Vamos a ver un ejemplo. El de interseccion con<br>un punto. El metodo evaluate podria ser algo como:<br><br><br>  public Object evaluate(EvaluatorData data) throws EvaluatorException {<br>    Geometry geom = (Geometry) data.getDataValue(&quot;the_geom&quot;);<br>    try {<br><br>      return punto.intersects(geom);<br><br>    } catch (GeometryOperationNotSupportedException e) {<br>      throw new EvaluatorException(e);<br>      <br>    } catch (GeometryOperationException e) {<br>      throw new EvaluatorException(e);<br>      <br>    }<br>  }<br><br><br>para cada feature de nuestra fuente de datos se llamara a este evaluate.<br>En data recibiremos los datos de la feature. Asumo que la geometria esta<br>en el campo &quot;the_geom&quot;, asi que lo primero es recuperar la geometria.<br>Luego, simplemente compruebo si intersecta con mi punto y devuelbo el <br>resultado (si intersecta o no).<br><br>La clase MyIntersectsEvaluator podia quedar algo como:<br><br><br>public class MyIntersectsEvaluator extends AbstractEvaluator {<br><br>  private Geometry punto;<br><br>  public MyIntersectsEvaluator(Geometry punto) throws GeometryOperationNotSupportedException, GeometryOperationException {<br>    this.punto = punto;<br>  }<br><br>  public String getName() {<br>    return &quot;IntersectaConPunto&quot;;<br>  }<br><br>  public Object evaluate(EvaluatorData data) throws EvaluatorException {<br>    Geometry geom = (Geometry) data.getDataValue(&quot;the_geom&quot;);<br>    try {<br><br>      return punto.intersects(geom);<br><br>    } catch (GeometryOperationNotSupportedException e) {<br>      throw new EvaluatorException(e);<br>      <br>    } catch (GeometryOperationException e) {<br>      throw new EvaluatorException(e);<br>      <br>    }<br>  }<br>  <br>} <br><br>Si creamos uno de estos y lo aplicamos al query como un filtro, el set solo nos<br>devolbera las features que intersecten con nuestro poligono.<br><br>Si lo dejamos asi funcionara, y con un shape, o un dxf, ira bien; pero con una<br>BBDD ira muy lento. Esto es por que la libreria de acceso a datos, se traera <br>todas las filas de la tabla y comprobara una a una si cumplen el criterio indicado.<br><br>Podemos optimizar esto añadiendo el metodo getCQL a nuestra clase con algo como:<br><br><br>  public String getCQL() {<br>    where = MessageFormat.format(<br>      &quot; intersects(the_geom, GeomFromText(&#39;{1}&#39;,&#39;{2}&#39;)) &quot;, <br>      new Object[] {<br>        punto.convertToWKT(),<br>        proj.getAbbrev()<br>      }<br>    ); <br>    return where;<br>  }<br>  <br>Y añadiremos en el constructo la rojeccion en la que se encuentra el poligono:<br><br>  public MyIntersectsEvaluator(Geometry punto, IProjection proj) throws GeometryOperationNotSupportedException, GeometryOperationException {<br>    this.punto = punto;<br>    this.proj = proj;<br>  }<br><br>¿ Que es lo que conseguimos con esto ?<br><br>Si aplicamos este filtro a un shape, nada. El resultado sera el mismo que antes.<br>Sim embargo, si lo aplicamos a un tabla de PostgreSQL tendremos unas mejoras <br>sustanciales en el rendimiento.<br><br>El proveedor de datos de PostgreSQL de gvSIG, ve que el metodo getCQL devuelbe<br>una cadena, y la añade al where de la sentencia SQL que va a usar para recuperar<br>los datos. Asi que la BBDD solo devolvera los datos que cumplan el criterio que<br>hemos indicado en esa funcion. Luego, la libreria de acceso a datos volvera a <br>aplicar el filtro de nuestro evaluador a cada una de las features recuperadas, pero<br>ya no sera a todas las de la tabla, si no solo a las que hayamos restringido con<br>lo que devuelba el getCQL.<br><br>Es muy importante que la proyeccion del punto y la de las geometrias de la tabla <br>de la BBDD sean la misma, si no los resultados pueden ser algo impredecibles.<br><br>Con gvSIG 2.3.3 y 2.4 se han añadido mejoras que permiten independizar como <br>construimos lo que devuelbe el getCQL de la BBDD que se esta usando para que <br>asi nuestra consulta funcione con todas las BBDD que soporte gvSIG, pero de<br>momento voy a dejarlo asi.<br><br>Tambien podriamos pasarle a muestra clase MyIntersectsEvaluator como se llama <br>la columna geometria con la que queremos comparar nuestro punto (por si no<br>se llama &quot;the_geom&quot;). Asi nuestra clase seria independiente de ese valor.<br><br>Sobre lo del buffer que comentas... en la clase IntersectsEvaluator que hay en <br>la implementacion de langregistryviewer no he visto que se haga ningun buffer, ni<br>tampoco antes de pasarle el punto sobre el que se realiza la interseccion. <br>¿ Podria ser que tuvieses en la fuente de datos geometrias que se superponen ?<br><br>Bueno, lo dejo aqui y ya vas preguntando cosas mas concretas.<br><br>Por cierto, el codigo lo he picado directamente aqui, podria haberme confundido<br>en el nombre de algun identificador, espero que no.<br><br>Un saludo<br>Joaquin<br><br clear="all"><br>-- <br><div class="gmail_signature">--------------------------------------<br>Joaquin Jose del Cerro Murciano<br>Development and software arquitecture manager at gvSIG Team<br><a href="mailto:jjdelcerro@gvsig.com" target="_blank">jjdelcerro@gvsig.com</a><br><a href="mailto:jjdelcerro@gvsig.org" target="_blank">jjdelcerro@gvsig.org</a><br>gvSIG Association<br><a href="http://www.gvsig.com" target="_blank">www.gvsig.com</a><br><a href="http://www.gvsig.org" target="_blank">www.gvsig.org</a></div>
</div></div>