Subversion Repositories hibernate-spatial

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
272 maesenka 1
package org.hibernatespatial.wkb;
2
 
3
import com.vividsolutions.jts.geom.Coordinate;
4
import com.vividsolutions.jts.geom.Geometry;
5
import org.hibernatespatial.jts.geom.CoordinateDimension;
6
import org.hibernatespatial.mgeom.MCoordinate;
7
 
8
/**
9
 * @author Karel Maesen, Geovise BVBA
10
 *         creation-date: Nov 11, 2010
11
 */
12
public abstract class WKBEncoder<G extends Geometry> {
13
 
14
 
15
    public Bytes encode(G geom) {
16
        return encode(geom, null);
17
    }
18
 
19
    public Bytes encode(G geom, WKBByteOrder wbo) {
20
        CoordinateDimension dimension = CoordinateDimension.valueFor(hasZ(geom), hasM(geom));
21
        Bytes output = Bytes.allocate(calculateSize(geom, dimension));
22
        if (wbo != null) {
23
            output.setWKBByteOrder(wbo);
24
        }
25
        writeByteOrder(output);
26
        writeTypeCodeAndSRID(geom, dimension, output);
27
        writeNumComponents(geom, output);
28
        writeComponents(geom, dimension, output);
29
        output.rewind();
30
        return output;
31
    }
32
 
33
    protected void writeByteOrder(Bytes output){
34
        output.put(output.getWKBByteOrder().byteValue());
35
    }
36
 
37
 
38
    protected void writeCoordinate(Coordinate coordinate, CoordinateDimension dimension, Bytes output) {
39
        output.putDouble(coordinate.x);
40
        output.putDouble(coordinate.y);
41
        if(dimension.hasZ()){
42
            output.putDouble(coordinate.z);
43
        }
44
        if (dimension.hasM()){
45
            double m = 0.0;
46
            if (coordinate instanceof MCoordinate){
47
                m = ((MCoordinate)coordinate).m;
48
            }
49
            output.putDouble(m);
50
        }
51
    }
52
 
53
    protected boolean hasM(Geometry geom) {
54
        Coordinate co = geom.getCoordinate();
55
        if (co instanceof MCoordinate) {
56
            return ! Double.isNaN(((MCoordinate)co).m);
57
        }
58
        return false;
59
    }
60
 
61
    protected boolean hasZ(Geometry geom) {
62
        return !Double.isNaN(geom.getCoordinate().z);
63
    }
64
 
65
    protected void writeTypeCodeAndSRID(G geometry, CoordinateDimension dimension, Bytes output){
66
            long typeCode = getGeometryType();
67
            boolean hasSRID = (geometry.getSRID() > 0);
68
            if (hasSRID)
69
                typeCode |= WKB.SRID_FLAG;
70
            if (dimension.hasM())
71
                typeCode |= WKB.M_FLAG;
72
            if (dimension.hasZ())
73
                typeCode |= WKB.Z_FLAG;
74
            output.putUInt(typeCode);
75
            if(hasSRID){
76
                output.putInt(geometry.getSRID());
77
            }
78
 
79
    }
80
 
81
    protected abstract long getGeometryType();
82
 
83
    protected abstract void writeNumComponents(G geometry, Bytes output);
84
 
85
    protected abstract void writeComponents(G geometry, CoordinateDimension dimension, Bytes output);
86
 
87
    protected abstract int calculateSize(G geom, CoordinateDimension dimension);
88
 
89
 
90
}