/* * citygml4j - The Open Source Java API for CityGML * https://github.com/citygml4j * * Copyright 2013-2017 Claus Nagel <claus.nagel@gmail.com> * * 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 org.citygml4j.util.walker; import java.util.ArrayList; import java.util.HashSet; import java.util.Set; import org.citygml4j.model.citygml.core.LodRepresentation; import org.citygml4j.model.citygml.texturedsurface._TexturedSurface; import org.citygml4j.model.common.visitor.GeometryVisitor; import org.citygml4j.model.gml.geometry.AbstractGeometry; import org.citygml4j.model.gml.geometry.GeometryArrayProperty; import org.citygml4j.model.gml.geometry.GeometryProperty; import org.citygml4j.model.gml.geometry.InlineGeometryProperty; import org.citygml4j.model.gml.geometry.aggregates.AbstractGeometricAggregate; import org.citygml4j.model.gml.geometry.aggregates.MultiCurve; import org.citygml4j.model.gml.geometry.aggregates.MultiGeometry; import org.citygml4j.model.gml.geometry.aggregates.MultiLineString; import org.citygml4j.model.gml.geometry.aggregates.MultiPoint; import org.citygml4j.model.gml.geometry.aggregates.MultiPolygon; import org.citygml4j.model.gml.geometry.aggregates.MultiSolid; import org.citygml4j.model.gml.geometry.aggregates.MultiSurface; import org.citygml4j.model.gml.geometry.complexes.CompositeCurve; import org.citygml4j.model.gml.geometry.complexes.CompositeSolid; import org.citygml4j.model.gml.geometry.complexes.CompositeSurface; import org.citygml4j.model.gml.geometry.complexes.GeometricComplex; import org.citygml4j.model.gml.geometry.primitives.AbstractCurve; import org.citygml4j.model.gml.geometry.primitives.AbstractGeometricPrimitive; import org.citygml4j.model.gml.geometry.primitives.AbstractRing; import org.citygml4j.model.gml.geometry.primitives.AbstractRingProperty; import org.citygml4j.model.gml.geometry.primitives.AbstractSolid; import org.citygml4j.model.gml.geometry.primitives.AbstractSurface; import org.citygml4j.model.gml.geometry.primitives.AbstractSurfacePatch; import org.citygml4j.model.gml.geometry.primitives.Curve; import org.citygml4j.model.gml.geometry.primitives.CurveProperty; import org.citygml4j.model.gml.geometry.primitives.GeometricPrimitiveProperty; import org.citygml4j.model.gml.geometry.primitives.LineString; import org.citygml4j.model.gml.geometry.primitives.LineStringProperty; import org.citygml4j.model.gml.geometry.primitives.LinearRing; import org.citygml4j.model.gml.geometry.primitives.OrientableCurve; import org.citygml4j.model.gml.geometry.primitives.OrientableSurface; import org.citygml4j.model.gml.geometry.primitives.Point; import org.citygml4j.model.gml.geometry.primitives.PointProperty; import org.citygml4j.model.gml.geometry.primitives.Polygon; import org.citygml4j.model.gml.geometry.primitives.PolygonProperty; import org.citygml4j.model.gml.geometry.primitives.Rectangle; import org.citygml4j.model.gml.geometry.primitives.Ring; import org.citygml4j.model.gml.geometry.primitives.Solid; import org.citygml4j.model.gml.geometry.primitives.SolidProperty; import org.citygml4j.model.gml.geometry.primitives.Surface; import org.citygml4j.model.gml.geometry.primitives.SurfacePatchArrayProperty; import org.citygml4j.model.gml.geometry.primitives.SurfaceProperty; import org.citygml4j.model.gml.geometry.primitives.Tin; import org.citygml4j.model.gml.geometry.primitives.Triangle; import org.citygml4j.model.gml.geometry.primitives.TriangulatedSurface; import org.citygml4j.model.gml.grids.Grid; import org.citygml4j.model.gml.grids.RectifiedGrid; public abstract class GeometryWalker implements GeometryVisitor, Walker { private Set<Object> visited = new HashSet<Object>(); private boolean shouldWalk = true; public void reset() { visited.clear(); shouldWalk = true; } public boolean shouldWalk() { return shouldWalk; } public void setShouldWalk(boolean shouldWalk) { this.shouldWalk = shouldWalk; } public boolean addToVisited(Object object) { return visited.add(object); } public boolean hasVisited(Object object) { return visited.contains(object); } public void visit(AbstractGeometry abstractGeometry) { } public void visit(LodRepresentation lodRepresentation) { if (lodRepresentation != null) { for (int lod = 0; lod < 5; lod++) { if (lodRepresentation.isSetLodGeometry(lod)) for (GeometryProperty<? extends AbstractGeometry> geometryProperty : lodRepresentation.getLodGeometry(lod)) visit(geometryProperty); } } } public void visit(AbstractGeometricPrimitive abstractGeometricPrimitive) { visit((AbstractGeometry)abstractGeometricPrimitive); } public void visit(AbstractGeometricAggregate abstractGeometricAggregate) { visit((AbstractGeometry)abstractGeometricAggregate); } public void visit(AbstractCurve abstractCurve) { visit((AbstractGeometricPrimitive)abstractCurve); } public void visit(AbstractSolid abstractSolid) { visit((AbstractGeometricPrimitive)abstractSolid); } public void visit(AbstractSurface abstractSurface) { visit((AbstractGeometricPrimitive)abstractSurface); } public void visit(AbstractRing abstractRing) { visit((AbstractGeometry)abstractRing); } public void visit(Triangle triangle) { if (triangle.isSetExterior()) visit(triangle.getExterior()); } public void visit(Rectangle rectangle) { if (rectangle.isSetExterior()) visit(rectangle.getExterior()); } public void visit(CompositeCurve compositeCurve) { visit((AbstractCurve)compositeCurve); for (CurveProperty curveProperty : new ArrayList<CurveProperty>(compositeCurve.getCurveMember())) visit(curveProperty); } public void visit(CompositeSolid compositeSolid) { visit((AbstractSolid)compositeSolid); for (SolidProperty solidProperty : new ArrayList<SolidProperty>(compositeSolid.getSolidMember())) visit(solidProperty); } public void visit(CompositeSurface compositeSurface) { visit((AbstractSurface)compositeSurface); for (SurfaceProperty surfaceProperty : new ArrayList<SurfaceProperty>(compositeSurface.getSurfaceMember())) visit(surfaceProperty); } public void visit(Curve curve) { visit((AbstractCurve)curve); } public void visit(GeometricComplex geometricComplex) { visit((AbstractGeometry)geometricComplex); if (geometricComplex.isSetElement()) for (GeometricPrimitiveProperty geometricPrimitiveProperty : new ArrayList<GeometricPrimitiveProperty>(geometricComplex.getElement())) visit(geometricPrimitiveProperty); } public void visit(Grid grid) { visit((AbstractGeometry)grid); } public void visit(LinearRing linearRing) { visit((AbstractRing)linearRing); } public void visit(LineString lineString) { visit((AbstractCurve)lineString); } public void visit(MultiCurve multiCurve) { visit((AbstractGeometricAggregate)multiCurve); if (multiCurve.isSetCurveMember()) for (CurveProperty curveProperty : new ArrayList<CurveProperty>(multiCurve.getCurveMember())) visit(curveProperty); if (multiCurve.isSetCurveMembers()) visit(multiCurve.getCurveMembers()); } public void visit(MultiGeometry multiGeometry) { visit((AbstractGeometricAggregate)multiGeometry); if (multiGeometry.isSetGeometryMember()) for (GeometryProperty<? extends AbstractGeometry> geometryProperty : new ArrayList<GeometryProperty<? extends AbstractGeometry>>(multiGeometry.getGeometryMember())) visit(geometryProperty); if (multiGeometry.isSetGeometryMembers()) visit(multiGeometry.getGeometryMembers()); } public void visit(MultiLineString multiLineString) { visit((AbstractGeometricAggregate)multiLineString); if (multiLineString.isSetLineStringMember()) for (LineStringProperty lineStringProperty : new ArrayList<LineStringProperty>(multiLineString.getLineStringMember())) visit(lineStringProperty); } public void visit(MultiPoint multiPoint) { visit((AbstractGeometricAggregate)multiPoint); if (multiPoint.isSetPointMember()) for (PointProperty pointProperty : new ArrayList<PointProperty>(multiPoint.getPointMember())) visit(pointProperty); if (multiPoint.isSetPointMembers()) visit(multiPoint.getPointMembers()); } public void visit(MultiPolygon multiPolygon) { visit((AbstractGeometricAggregate)multiPolygon); if (multiPolygon.isSetPolygonMember()) for (PolygonProperty polygonProperty : new ArrayList<PolygonProperty>(multiPolygon.getPolygonMember())) visit(polygonProperty); } public void visit(MultiSolid multiSolid) { visit((AbstractGeometricAggregate)multiSolid); if (multiSolid.isSetSolidMember()) for (SolidProperty solidProperty : new ArrayList<SolidProperty>(multiSolid.getSolidMember())) visit(solidProperty); if (multiSolid.isSetSolidMembers()) visit(multiSolid.getSolidMembers()); } public void visit(MultiSurface multiSurface) { visit((AbstractGeometricAggregate)multiSurface); if (multiSurface.isSetSurfaceMember()) for (SurfaceProperty surfaceProperty : new ArrayList<SurfaceProperty>(multiSurface.getSurfaceMember())) visit(surfaceProperty); if (multiSurface.isSetSurfaceMembers()) visit(multiSurface.getSurfaceMembers()); } public void visit(OrientableCurve orientableCurve) { visit((AbstractCurve)orientableCurve); if (orientableCurve.isSetBaseCurve()) visit(orientableCurve.getBaseCurve()); } public void visit(OrientableSurface orientableSurface) { visit((AbstractSurface)orientableSurface); if (orientableSurface.isSetBaseSurface()) visit(orientableSurface.getBaseSurface()); } public void visit(_TexturedSurface texturedSurface) { visit((OrientableSurface)texturedSurface); } public void visit(Point point) { visit((AbstractGeometricPrimitive)point); } public void visit(Polygon polygon) { visit((AbstractSurface)polygon); if (polygon.isSetExterior()) visit(polygon.getExterior()); if (polygon.isSetInterior()) for (AbstractRingProperty interior : new ArrayList<AbstractRingProperty>(polygon.getInterior())) visit(interior); } public void visit(RectifiedGrid rectifiedGrid) { visit((Grid)rectifiedGrid); if (rectifiedGrid.isSetOrigin()) visit(rectifiedGrid.getOrigin()); } public void visit(Ring ring) { visit((AbstractRing)ring); if (ring.isSetCurveMember()) for (CurveProperty curveProperty : new ArrayList<CurveProperty>(ring.getCurveMember())) visit(curveProperty); } public void visit(Solid solid) { visit((AbstractSolid)solid); if (solid.isSetExterior()) visit(solid.getExterior()); if (solid.isSetInterior()) for (SurfaceProperty interior : new ArrayList<SurfaceProperty>(solid.getInterior())) visit(interior); } public void visit(Surface surface) { visit((AbstractSurface)surface); if (surface.isSetPatches()) visit(surface.getPatches()); } public void visit(Tin tin) { visit((TriangulatedSurface)tin); } public void visit(TriangulatedSurface triangulatedSurface) { visit((Surface)triangulatedSurface); } public <T extends AbstractGeometry> void visit(GeometryProperty<T> geometryProperty) { if (geometryProperty.isSetGeometry() && shouldWalk && visited.add(geometryProperty.getGeometry())) geometryProperty.getGeometry().accept(this); } public <T extends AbstractGeometry> void visit(InlineGeometryProperty<T> geometryProperty) { if (geometryProperty.isSetGeometry() && shouldWalk && visited.add(geometryProperty.getGeometry())) geometryProperty.getGeometry().accept(this); } public <T extends AbstractGeometry> void visit(GeometryArrayProperty<T> geometryArrayProperty) { if (geometryArrayProperty.isSetGeometry()) { for (AbstractGeometry abstractGeometry : new ArrayList<AbstractGeometry>(geometryArrayProperty.getGeometry())) if (shouldWalk && visited.add(abstractGeometry)) abstractGeometry.accept(this); } } public void visit(SurfacePatchArrayProperty surfacePatchArrayProperty) { if (surfacePatchArrayProperty.isSetSurfacePatch()) for (AbstractSurfacePatch abstractSurfacePatch : new ArrayList<AbstractSurfacePatch>(surfacePatchArrayProperty.getSurfacePatch())) { if (shouldWalk && visited.add(abstractSurfacePatch)) { if (abstractSurfacePatch instanceof Triangle) visit((Triangle)abstractSurfacePatch); else if (abstractSurfacePatch instanceof Rectangle) visit((Rectangle)abstractSurfacePatch); } } } }