/* Copyright 2015 The jeo project. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.jeo.geobuf;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Collections;
import java.util.Map;
import io.jeo.data.Driver;
import io.jeo.data.FileData;
import io.jeo.geobuf.Geobuf.Data.DataTypeCase;
import io.jeo.geom.Bounds;
import io.jeo.util.Util;
import io.jeo.vector.FeatureAppendCursor;
import io.jeo.vector.FeatureCursor;
import io.jeo.vector.FeatureWriteCursor;
import io.jeo.vector.Features;
import io.jeo.vector.VectorQuery;
import io.jeo.vector.VectorDataset;
import io.jeo.vector.Schema;
import io.jeo.util.Key;
import io.jeo.vector.VectorQueryPlan;
import org.osgeo.proj4j.CoordinateReferenceSystem;
public class GeobufDataset implements VectorDataset, FileData {
File file;
GeobufReader reader;
public GeobufDataset(File file) throws IOException {
this.file = file;
}
@Override
public Schema schema() throws IOException {
return Features.schema(this).orElse(null);
}
@Override
public Driver<?> driver() {
return new Gbf();
}
@Override
public Map<Key<?>, Object> driverOptions() {
return (Map) Collections.singletonMap(Gbf.FILE, file);
}
@Override
public File file() {
return file;
}
@Override
public String name() {
return Util.base(file.getName());
}
@Override
public CoordinateReferenceSystem crs() throws IOException {
return reader().crs();
}
@Override
public Bounds bounds() throws IOException {
return read(new VectorQuery()).bounds();
}
@Override
public long count(VectorQuery q) throws IOException {
return read(q).count();
}
@Override
public FeatureCursor read(VectorQuery q) throws IOException {
return new VectorQueryPlan(q).apply(reader().featureCollection());
}
@Override
public FeatureWriteCursor update(VectorQuery q) throws IOException {
throw new IOException("Update cursor not supported");
}
@Override
public FeatureAppendCursor append(VectorQuery q) throws IOException {
if (!fileIsEmpty()) {
throw new IOException("Can't append to non empty dataset");
}
return new GeobufAppendCursor(this);
}
@Override
public void close() {
if (reader != null) {
reader.close();
reader = null;
}
}
GeobufReader reader() throws IOException {
if (reader == null) {
reader = new GeobufReader(Files.newInputStream(file.toPath()));
if (reader.data.getDataTypeCase() != DataTypeCase.FEATURE_COLLECTION) {
// TODO: wrap geometry and feature?
throw new IOException("Geobuf not a feature collection");
}
}
return reader;
}
GeobufWriter writer() throws IOException {
return new GeobufWriter(Files.newOutputStream(file.toPath()));
}
boolean fileIsEmpty() {
return !file.exists() || file.length() == 0;
}
}