All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.wikibrain.spatial.dao.postgis.PostGISSpatialDataDao Maven / Gradle / Ivy

The newest version!
package org.wikibrain.spatial.dao.postgis;

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.typesafe.config.Config;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.Point;
import org.geotools.data.collection.ListFeatureCollection;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureStore;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.opengis.feature.simple.SimpleFeature;
import org.wikibrain.conf.Configuration;
import org.wikibrain.conf.ConfigurationException;
import org.wikibrain.conf.Configurator;
import org.wikibrain.core.WikiBrainException;
import org.wikibrain.core.dao.DaoException;
import org.wikibrain.core.dao.LocalPageDao;
import org.wikibrain.core.lang.Language;
import org.wikibrain.core.model.LocalPage;
import org.wikibrain.core.model.NameSpace;
import org.wikibrain.core.model.Title;
import org.wikibrain.spatial.SpatialContainerMetadata;
import org.wikibrain.spatial.constants.Precision;
import org.wikibrain.spatial.constants.RefSys;
import org.wikibrain.spatial.dao.SpatialDataDao;
import org.wikibrain.wikidata.WikidataDao;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.ArrayBlockingQueue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Created by bjhecht on 4/7/14.
 */
public class PostGISSpatialDataDao implements SpatialDataDao {

    private final PostGISDB db;
    private final WikidataDao wikidataDao;
    private final LocalPageDao localPageDao;

    // for writing data
    private ArrayBlockingQueue curFeaturesToStore = null;
    private ThreadLocal simpleFeatureBuilder;
    private static final Integer BUFFER_SIZE = 200;

    private static final Logger LOG = LoggerFactory.getLogger(PostGISDB.class);

    private PostGISSpatialDataDao(PostGISDB postGisDb, WikidataDao wikidataDao, LocalPageDao localPageDao){
        this.db = postGisDb;
        this.wikidataDao = wikidataDao;
        this.localPageDao = localPageDao;
        this.curFeaturesToStore = new ArrayBlockingQueue(BUFFER_SIZE * 10);
        simpleFeatureBuilder = new ThreadLocal() {
            @Override
            public SimpleFeatureBuilder initialValue() {
                try {
                    return new SimpleFeatureBuilder(db.getSchema());
                } catch (DaoException e) {
                    throw new RuntimeException(e);
                }
            }
        };
    }

    @Override
    public Geometry getGeometry(int itemId, String layerName, String refSysName) throws DaoException {

        return db.getGeometry(itemId, layerName, refSysName);

    }

    @Override
    public Map getGeometries(int itemId) throws DaoException {
        Map result = new HashMap();
        for (String refSys : this.getAllRefSysNames()){
            for (String layer : this.getAllLayerNames(refSys)){
                Geometry g = getGeometry(itemId, layer, refSys);
                if (g != null) {
                    result.put(layer, g);
                }
            }
        }
        return result;
    }

    @Override
    public Map getAllGeometriesInLayer(String layerName, String refSysName) throws DaoException {
        return db.getAllGeometriesInLayer(layerName, refSysName);
    }

    @Override
    public Map getAllGeometriesInLayer(String layerName) throws DaoException {
        return getAllGeometriesInLayer(layerName, RefSys.EARTH);
    }

    @Override
    public Map getAllGeometriesInLayer(String layerName, Precision.LatLonPrecision minPrecision) throws DaoException {

        Map geoms = getAllGeometriesInLayer(layerName);
        Set keys = Sets.newHashSet();

        for (Integer curKey : keys){
            Geometry g = geoms.get(curKey);
            if (this.filterByPrecision(g, minPrecision) == null){
                geoms.remove(curKey);
            }
        }

        return geoms;

    }

    @Override
    public Map getAllGeometriesInLayer(String layerName, String[] notInLayers, String refSysName) throws DaoException {

        Map rVal = this.getAllGeometriesInLayer(layerName, refSysName);

        for (String notInLayer : notInLayers){
            Map temp = this.getAllGeometriesInLayer(notInLayer, refSysName);
            if (temp != null) {
                for (Integer key : temp.keySet()) {
                    rVal.remove(key);
                }
            }else{
                LOG.warn("Could not find any geometries in layer: " + layerName);
            }
        }

        return rVal;

    }

    @Override
    public Iterable getAllRefSysNames() throws DaoException {
        return db.getAllReferenceSystems();
    }

    @Override
    public Iterable getAllLayerNames(String refSysName) throws DaoException {
        return db.getLayersInReferenceSystem(refSysName);
    }

    @Override
    public SpatialContainerMetadata getReferenceSystemMetadata(String refSysName) throws DaoException {

        try{
            int count = 0;
            SpatialContainerMetadata rVal = null;
            for (String layerName : getAllLayerNames(refSysName)){
                if (rVal == null){
                    rVal = getLayerMetadata(layerName, refSysName);
                }else{
                    rVal.merge(getLayerMetadata(layerName, refSysName));
                }
                count++;
            }
            rVal.toReferenceSystem();
            return rVal;
        }catch(WikiBrainException e){
            throw new DaoException(e);
        }


    }

    @Override
    public SpatialContainerMetadata getLayerMetadata(String layerName, String refSysName) throws DaoException {

        SpatialContainerMetadata rVal = db.getLayerMetadata(layerName, refSysName);
        return rVal;

    }

    @Override
    public Geometry getGeometry(int itemId, String layerName) throws DaoException {
        return getGeometry(itemId, layerName, RefSys.EARTH);
    }

    @Override
    public Geometry getGeometry(int itemId, String layerName, Precision.LatLonPrecision minPrecision) throws DaoException {

        Geometry g = this.getGeometry(itemId, layerName);
        return filterByPrecision(g, minPrecision);

    }


    @Override
    public Geometry getGeometry(String articleName, Language language, String layerName) throws DaoException {

        return getGeometry(articleName, language, layerName, RefSys.EARTH);

    }

    private Geometry filterByPrecision(Geometry g, Precision.LatLonPrecision minPrecision){

        if (g == null) return null;

        if (!(g instanceof Point)) return g;

        if (Precision.isGreaterThanOrEqualTo(Precision.getLatLonPrecision((Point)g), minPrecision)){
            return g;
        }else{
            return null;
        }

    }

    @Override
    public Geometry getGeometry(String articleName, Language language, String layerName, Precision.LatLonPrecision minPrecision) throws DaoException {

        Geometry g = getGeometry(articleName, language, layerName);
        return filterByPrecision(g, minPrecision);

    }

    @Override
    public Geometry getGeometry(String articleName, Language language, String layerName, String refSysName) throws DaoException {

        LocalPage lp = localPageDao.getByTitle(new Title(articleName, language), NameSpace.ARTICLE);
        if (lp == null) return null;
        Integer id = wikidataDao.getItemId(lp);
        if (id == null) throw new DaoException("Could not find Wikidata item for \"" + lp.toString() + "\"");

        return getGeometry(id, layerName);
    }

    @Override
    public Map getBulkGeometriesInLayer(List idList, String layerName, String refSysName) throws DaoException{
        return db.getBulkGeometriesInLayer(idList, layerName, refSysName);
    }


    @Override
    public void beginSaveGeometries() throws DaoException {
        try {
            curFeaturesToStore.clear();
        }catch(Exception e){
            throw new DaoException(e);
        }
    }

    @Override
    public void endSaveGeometries() throws DaoException {
        flushFeatureBuffer(true);
    }

    private void flushFeatureBuffer(boolean force) throws DaoException{
        try {
            List batch = new ArrayList();
            synchronized (curFeaturesToStore) {
                if (!force && curFeaturesToStore.size() < BUFFER_SIZE) {
                    return;
                }
                curFeaturesToStore.drainTo(batch);
            }
            SimpleFeatureCollection featuresToStore = new ListFeatureCollection(db.getSchema(), batch);
            ((SimpleFeatureStore) db.getFeatureSource()).addFeatures(featuresToStore); // GeoTools can be so weird sometimes
        }catch(IOException e){
            throw new DaoException(e);
        }
    }

    @Override
    public void saveGeometry(int itemId, String layerName, String refSysName, Geometry g) throws DaoException {

        try {
            SimpleFeature curFeature = simpleFeatureBuilder.get().buildFeature("n/a", new Object[]{new Integer(itemId), layerName, refSysName, g});
            curFeaturesToStore.put(curFeature);
            if (curFeaturesToStore.size() > BUFFER_SIZE){
                flushFeatureBuffer(false);
            }


        }catch(Exception e){
            throw new DaoException(e);
        }

    }

    @Override
    public void removeLayer(String refSysName, String layerName) throws DaoException {
        db.removeLayer(refSysName, layerName);
    }

    @Override
    public void optimize() throws DaoException {
        db.optimize();
    }

    public static class Provider extends org.wikibrain.conf.Provider {
        public Provider(Configurator configurator, Configuration config) throws ConfigurationException {
            super(configurator, config);
        }

        @Override
        public Class getType() {
            return SpatialDataDao.class;
        }

        @Override
        public String getPath() {
            return "spatial.dao.spatialData";
        }

        @Override
        public PostGISSpatialDataDao get(String name, Config config,
                                         Map runtimeParams) throws ConfigurationException {

            return new PostGISSpatialDataDao( getConfigurator().get(PostGISDB.class, config.getString("dataSource")),
                    getConfigurator().get(WikidataDao.class), getConfigurator().get(LocalPageDao.class));

        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy