svn-gvsig-desktop / branches / org.gvsig.desktop-cvsgis1 / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.geometry / org.gvsig.fmap.geometry.jts / src / main / java / org / gvsig / fmap / geom / jts / aggregate / AbstractMultiPolygon.java @ 45267
History | View | Annotate | Download (7.14 KB)
1 | 42269 | fdiaz | /* gvSIG. Desktop Geographic Information System.
|
---|---|---|---|
2 | *
|
||
3 | * Copyright ? 2007-2015 gvSIG Association
|
||
4 | *
|
||
5 | * This program is free software; you can redistribute it and/or
|
||
6 | * modify it under the terms of the GNU General Public License
|
||
7 | * as published by the Free Software Foundation; either version 2
|
||
8 | * of the License, or (at your option) any later version.
|
||
9 | *
|
||
10 | * This program is distributed in the hope that it will be useful,
|
||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
13 | * GNU General Public License for more details.
|
||
14 | *
|
||
15 | * You should have received a copy of the GNU General Public License
|
||
16 | * along with this program; if not, write to the Free Software
|
||
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||
18 | * MA 02110-1301, USA.
|
||
19 | *
|
||
20 | * For any additional information, do not hesitate to contact us
|
||
21 | * at info AT gvsig.com, or visit our website www.gvsig.com.
|
||
22 | */
|
||
23 | package org.gvsig.fmap.geom.jts.aggregate; |
||
24 | |||
25 | 42283 | fdiaz | import java.awt.Shape; |
26 | 42274 | fdiaz | import java.awt.geom.AffineTransform; |
27 | import java.awt.geom.PathIterator; |
||
28 | import java.util.ArrayList; |
||
29 | 42358 | fdiaz | import java.util.Collections; |
30 | 42274 | fdiaz | import java.util.Iterator; |
31 | import java.util.List; |
||
32 | |||
33 | 42283 | fdiaz | import org.apache.commons.lang3.StringUtils; |
34 | 42274 | fdiaz | |
35 | 42283 | fdiaz | import org.gvsig.fmap.geom.Geometry; |
36 | 42269 | fdiaz | import org.gvsig.fmap.geom.aggregate.MultiPolygon; |
37 | 42274 | fdiaz | import org.gvsig.fmap.geom.jts.GeometryJTS; |
38 | 42277 | fdiaz | import org.gvsig.fmap.geom.jts.gputils.DefaultGeneralPathX; |
39 | import org.gvsig.fmap.geom.jts.gputils.GeneralPathXIterator; |
||
40 | 42274 | fdiaz | import org.gvsig.fmap.geom.jts.util.JTSUtils; |
41 | 42281 | fdiaz | import org.gvsig.fmap.geom.operation.GeometryOperationException; |
42 | import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException; |
||
43 | 42274 | fdiaz | import org.gvsig.fmap.geom.primitive.GeneralPathX; |
44 | 43244 | jjdelcerro | import org.gvsig.fmap.geom.primitive.Polygon; |
45 | 42274 | fdiaz | import org.gvsig.fmap.geom.primitive.Primitive; |
46 | 42283 | fdiaz | import org.gvsig.fmap.geom.primitive.Surface; |
47 | import org.gvsig.fmap.geom.type.GeometryType; |
||
48 | 42269 | fdiaz | |
49 | |||
50 | /**
|
||
51 | * @author fdiaz
|
||
52 | *
|
||
53 | */
|
||
54 | public abstract class AbstractMultiPolygon extends AbstractMultiSurface implements MultiPolygon { |
||
55 | |||
56 | /**
|
||
57 | *
|
||
58 | */
|
||
59 | private static final long serialVersionUID = 6663703214829442424L; |
||
60 | |||
61 | public AbstractMultiPolygon(int subtype) { |
||
62 | 42283 | fdiaz | super(Geometry.TYPES.MULTIPOLYGON, subtype);
|
63 | 42269 | fdiaz | } |
64 | |||
65 | 42274 | fdiaz | public com.vividsolutions.jts.geom.Geometry getJTS() {
|
66 | 42283 | fdiaz | com.vividsolutions.jts.geom.Polygon[] polygons = new com.vividsolutions.jts.geom.Polygon[primitives.size()]; |
67 | for (int i=0; i<primitives.size(); i++){ |
||
68 | polygons[i] = (com.vividsolutions.jts.geom.Polygon) ((GeometryJTS)primitives.get(i)).getJTS(); |
||
69 | 42274 | fdiaz | } |
70 | 42283 | fdiaz | return JTSUtils.createJTSMultiPolygon(polygons);
|
71 | 42274 | fdiaz | } |
72 | 42269 | fdiaz | |
73 | 44612 | jjdelcerro | @Override
|
74 | public Geometry force2D() throws GeometryOperationNotSupportedException, GeometryOperationException { |
||
75 | MultiPolygon2D other = new MultiPolygon2D();
|
||
76 | other.setProjection(this.getProjection());
|
||
77 | other.ensureCapacity(primitives.size()); |
||
78 | for (Primitive primitive : primitives) {
|
||
79 | other.addPrimitive((Primitive)primitive.force2D()); |
||
80 | } |
||
81 | return other;
|
||
82 | } |
||
83 | |||
84 | @Override
|
||
85 | 42274 | fdiaz | public PathIterator getPathIterator(AffineTransform at) { |
86 | 42283 | fdiaz | MultiPolygonIterator pi = new MultiPolygonIterator(at);
|
87 | return pi;
|
||
88 | 42274 | fdiaz | } |
89 | |||
90 | 44612 | jjdelcerro | @Override
|
91 | 42274 | fdiaz | public PathIterator getPathIterator(AffineTransform at, double flatness) { |
92 | 42275 | fdiaz | return getPathIterator(at);
|
93 | 42274 | fdiaz | } |
94 | |||
95 | 44612 | jjdelcerro | @Override
|
96 | 42274 | fdiaz | public GeneralPathX getGeneralPath() {
|
97 | 42277 | fdiaz | return new DefaultGeneralPathX(getPathIterator(null), false, 0); |
98 | 42274 | fdiaz | } |
99 | |||
100 | 42283 | fdiaz | |
101 | 44612 | jjdelcerro | @Override
|
102 | 42283 | fdiaz | public void flip() throws GeometryOperationNotSupportedException, GeometryOperationException { |
103 | for (Iterator iterator = primitives.iterator(); iterator.hasNext();) { |
||
104 | ((GeometryJTS)iterator.next()).flip(); |
||
105 | } |
||
106 | 42358 | fdiaz | Collections.reverse(primitives);
|
107 | 42283 | fdiaz | } |
108 | |||
109 | 44612 | jjdelcerro | @Override
|
110 | 42283 | fdiaz | public void addSurface(Surface surface) { |
111 | GeometryType geometryType = surface.getGeometryType(); |
||
112 | if(geometryType.getType() == Geometry.TYPES.POLYGON && geometryType.getSubType() == getGeometryType().getSubType()){
|
||
113 | primitives.add(surface); |
||
114 | return;
|
||
115 | } |
||
116 | String msg = StringUtils.replaceEach(
|
||
117 | "Only a polygon subtype %(subtypeSurface)s can be added to a MultiPolygon subtype %(subtype)s",
|
||
118 | new String[]{"%(subtypeSurface)s","%(subtype)s"}, |
||
119 | new String[]{String.valueOf(geometryType.getSubType()), String.valueOf(getGeometryType().getSubType())} |
||
120 | ); |
||
121 | 45267 | jjdelcerro | LOGGER.warn(msg); |
122 | 42283 | fdiaz | throw new UnsupportedOperationException(msg); |
123 | |||
124 | } |
||
125 | |||
126 | 44612 | jjdelcerro | @Override
|
127 | 42283 | fdiaz | public Shape getShape(AffineTransform affineTransform) { |
128 | 43244 | jjdelcerro | int capacity = 0; |
129 | for( int i = 0; i < this.getPrimitivesNumber(); i++ ) { |
||
130 | Polygon polygon = (Polygon) this.getPrimitiveAt(i); |
||
131 | capacity += polygon.getNumVertices(); |
||
132 | for( int r = 0; r < polygon.getNumInteriorRings(); r++ ) { |
||
133 | capacity += polygon.getInteriorRing(r).getNumVertices(); |
||
134 | } |
||
135 | } |
||
136 | return new DefaultGeneralPathX(getPathIterator(affineTransform),false,0, capacity); |
||
137 | 42283 | fdiaz | } |
138 | |||
139 | 44612 | jjdelcerro | @Override
|
140 | 42283 | fdiaz | public Shape getShape() { |
141 | return getShape(null); |
||
142 | } |
||
143 | |||
144 | 42277 | fdiaz | protected class MultiPolygonIterator extends GeneralPathXIterator { |
145 | |||
146 | /** Transform applied on the coordinates during iteration */
|
||
147 | 44612 | jjdelcerro | private final AffineTransform at; |
148 | 42277 | fdiaz | |
149 | /** True when the point has been read once */
|
||
150 | private boolean done; |
||
151 | private int index = 0; |
||
152 | 44612 | jjdelcerro | private final List<PathIterator>iterators; |
153 | 42277 | fdiaz | |
154 | public MultiPolygonIterator(AffineTransform at) { |
||
155 | super(new GeneralPathX()); |
||
156 | 44612 | jjdelcerro | this.iterators = new ArrayList<>(primitives.size()); |
157 | 42277 | fdiaz | if (at == null) { |
158 | at = new AffineTransform(); |
||
159 | } |
||
160 | |||
161 | this.at = at;
|
||
162 | 44612 | jjdelcerro | for (Primitive primitive : primitives) {
|
163 | 42277 | fdiaz | iterators.add(primitive.getPathIterator(at)); |
164 | } |
||
165 | done = false;
|
||
166 | } |
||
167 | |||
168 | 44612 | jjdelcerro | /*
|
169 | 42277 | fdiaz | * Return the winding rule for determining the interior of the path.
|
170 | *
|
||
171 | * @return <code>WIND_EVEN_ODD</code> by default.
|
||
172 | */
|
||
173 | 44612 | jjdelcerro | @Override
|
174 | 42277 | fdiaz | public int getWindingRule() { |
175 | return PathIterator.WIND_EVEN_ODD; |
||
176 | } |
||
177 | |||
178 | 44612 | jjdelcerro | /*
|
179 | 42277 | fdiaz | * @see java.awt.geom.PathIterator#next()
|
180 | */
|
||
181 | 44612 | jjdelcerro | @Override
|
182 | 42277 | fdiaz | public void next() { |
183 | PathIterator pathIteratorPrimitive = iterators.get(index);
|
||
184 | pathIteratorPrimitive.next(); |
||
185 | if(pathIteratorPrimitive.isDone()){
|
||
186 | index++; |
||
187 | done = (index==primitives.size()); |
||
188 | } |
||
189 | } |
||
190 | |||
191 | 44612 | jjdelcerro | /*
|
192 | 42277 | fdiaz | * @see java.awt.geom.PathIterator#isDone()
|
193 | */
|
||
194 | 44612 | jjdelcerro | @Override
|
195 | 42277 | fdiaz | public boolean isDone() { |
196 | return done;
|
||
197 | } |
||
198 | |||
199 | 44612 | jjdelcerro | /*
|
200 | 42277 | fdiaz | * @see java.awt.geom.PathIterator#currentSegment(double[])
|
201 | */
|
||
202 | 44612 | jjdelcerro | @Override
|
203 | 42277 | fdiaz | public int currentSegment(double[] coords) { |
204 | return iterators.get(index).currentSegment(coords);
|
||
205 | } |
||
206 | |||
207 | /*
|
||
208 | * @see java.awt.geom.PathIterator#currentSegment(float[])
|
||
209 | */
|
||
210 | 44612 | jjdelcerro | @Override
|
211 | 42277 | fdiaz | public int currentSegment(float[] coords) { |
212 | return iterators.get(index).currentSegment(coords);
|
||
213 | } |
||
214 | } |
||
215 | |||
216 | 42269 | fdiaz | } |