package mil.nga.giat.geowave.format.stanag4676.parser; import java.io.IOException; import java.io.InputStream; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.TimeZone; import java.util.UUID; import mil.nga.giat.geowave.format.stanag4676.parser.model.Area; import mil.nga.giat.geowave.format.stanag4676.parser.model.ClassificationCredibility; import mil.nga.giat.geowave.format.stanag4676.parser.model.ClassificationLevel; import mil.nga.giat.geowave.format.stanag4676.parser.model.CovarianceMatrix; import mil.nga.giat.geowave.format.stanag4676.parser.model.ExerciseIndicator; import mil.nga.giat.geowave.format.stanag4676.parser.model.MissionFrame; import mil.nga.giat.geowave.format.stanag4676.parser.model.GeodeticPosition; import mil.nga.giat.geowave.format.stanag4676.parser.model.IDdata; import mil.nga.giat.geowave.format.stanag4676.parser.model.Identity; import mil.nga.giat.geowave.format.stanag4676.parser.model.LineageRelation; import mil.nga.giat.geowave.format.stanag4676.parser.model.MissionSummary; import mil.nga.giat.geowave.format.stanag4676.parser.model.MissionSummaryMessage; import mil.nga.giat.geowave.format.stanag4676.parser.model.ModalityType; import mil.nga.giat.geowave.format.stanag4676.parser.model.MotionEventPoint; import mil.nga.giat.geowave.format.stanag4676.parser.model.MotionImagery; import mil.nga.giat.geowave.format.stanag4676.parser.model.NATO4676Message; import mil.nga.giat.geowave.format.stanag4676.parser.model.ObjectClassification; import mil.nga.giat.geowave.format.stanag4676.parser.model.Security; import mil.nga.giat.geowave.format.stanag4676.parser.model.SimulationIndicator; import mil.nga.giat.geowave.format.stanag4676.parser.model.SymbolicSpectralRange; import mil.nga.giat.geowave.format.stanag4676.parser.model.Track; import mil.nga.giat.geowave.format.stanag4676.parser.model.TrackClassification; import mil.nga.giat.geowave.format.stanag4676.parser.model.TrackEnvironment; import mil.nga.giat.geowave.format.stanag4676.parser.model.TrackEvent; import mil.nga.giat.geowave.format.stanag4676.parser.model.TrackIdentity; import mil.nga.giat.geowave.format.stanag4676.parser.model.TrackManagement; import mil.nga.giat.geowave.format.stanag4676.parser.model.TrackMessage; import mil.nga.giat.geowave.format.stanag4676.parser.model.TrackPoint; import mil.nga.giat.geowave.format.stanag4676.parser.model.TrackPointDetail; import mil.nga.giat.geowave.format.stanag4676.parser.model.TrackPointType; import mil.nga.giat.geowave.format.stanag4676.parser.model.TrackStatus; import mil.nga.giat.geowave.format.stanag4676.parser.model.TrackerType; import org.apache.commons.io.IOUtils; import org.jdom.Attribute; import org.jdom.Document; import org.jdom.Element; import org.jdom.JDOMException; import org.jdom.Namespace; import org.jdom.input.JDOMParseException; import org.jdom.input.SAXBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class NATO4676Decoder implements TrackDecoder { HashMap<String, Track> trackMap = new HashMap<String, Track>(); private int trackStatsNumTracks = 0; private int trackStatsNumDots = 0; private static final Logger LOGGER = LoggerFactory.getLogger(NATO4676Decoder.class); boolean printNotParse = false; @Override public void initialize() { trackStatsNumTracks = 0; trackStatsNumDots = 0; } public void setPrintNotParse( final boolean shouldPrint ) { printNotParse = shouldPrint; } @Override public NATO4676Message readNext( final InputStream is ) { NATO4676Message msg = null; try { if (printNotParse) { final String trackStr = IOUtils.toString( is, "UTF-8"); is.reset(); } else { final SAXBuilder builder = new SAXBuilder(); final Document doc = builder.build(is); final Element rootEl = doc.getRootElement(); final Namespace xmlns = rootEl.getNamespace(); String name = rootEl.getName(); if ("TrackMessage".equals(name)) { msg = readTrackMessage( rootEl, xmlns); LOGGER.info("TrackMessage read " + trackStatsNumTracks + " Tracks and " + trackStatsNumDots + " TrackPoints."); } else if ("MissionSummary".equals(name)) { msg = readMissionSummaryMessage( rootEl, xmlns); } } } catch (final JDOMParseException jdomPe) { LOGGER.info( "jdomParseException: " + jdomPe.getLocalizedMessage(), jdomPe); return null; } catch (final IOException ioe) { LOGGER.info( "IO exception: " + ioe.getLocalizedMessage(), ioe); return null; } catch (final JDOMException jdome) { LOGGER.info( "jdomException: " + jdome.getLocalizedMessage(), jdome); return null; } return msg; } private MissionSummaryMessage readMissionSummaryMessage( final Element element, final Namespace xmlns ) { final MissionSummaryMessage msg = new MissionSummaryMessage(); MissionSummary missionSummary = msg.getMissionSummary(); final List<Element> children = element.getChildren(); final Iterator<Element> childIter = children.iterator(); while (childIter.hasNext()) { final Element child = childIter.next(); final String childName = child.getName(); final String childValue = child.getValue(); if ("missionID".equals(childName)) { missionSummary.setMissionId(childValue); } else if ("Name".equals(childName)) { missionSummary.setName(childValue); } else if ("Security".equals(childName)) { msg.setSecurity(readSecurity( child, xmlns)); missionSummary.setSecurity(msg.getSecurity().getClassification().toString()); } else if ("msgCreatedTime".equals(childName)) { msg.setMessageTime(DateStringToLong(childValue)); } else if ("senderId".equals(childName)) { msg.setSenderID(readIDdata( child, xmlns)); } else if ("StartTime".equals(childName)) { missionSummary.setStartTime(DateStringToLong(childValue)); } else if ("EndTime".equals(childName)) { missionSummary.setEndTime(DateStringToLong(childValue)); } else if ("FrameInformation".equals(childName)) { missionSummary.addFrame(readFrame( child, xmlns)); } else if ("CoverageArea".equals(childName)) { missionSummary.setCoverageArea(readCoverageArea( child, xmlns)); } else if ("ActiveObjectClassifications".equals(childName)) { missionSummary.setClassifications(readObjectClassifications( child, xmlns)); } } return msg; } private List<ObjectClassification> readObjectClassifications( final Element element, final Namespace xmlns ) { final List<ObjectClassification> objClassList = new ArrayList<ObjectClassification>(); final List<Element> children = element.getChildren(); final Iterator<Element> childIter = children.iterator(); while (childIter.hasNext()) { final Element child = childIter.next(); final String childName = child.getName(); final String childValue = child.getValue(); if ("classification".equals(childName)) { ObjectClassification classification = ObjectClassification.fromString(childValue); if (classification != null) objClassList.add(classification); } } return objClassList; } private MissionFrame readFrame( final Element element, final Namespace xmlns ) { final MissionFrame frame = new MissionFrame(); final List<Element> children = element.getChildren(); final Iterator<Element> childIter = children.iterator(); while (childIter.hasNext()) { final Element child = childIter.next(); final String childName = child.getName(); final String childValue = child.getValue(); if ("frameNumber".equals(childName)) { frame.setFrameNumber(Integer.parseInt(childValue)); } else if ("frameTimestamp".equals(childName)) { frame.setFrameTime(DateStringToLong(childValue)); } else if ("frameCoverageArea".equals(childName)) { frame.setCoverageArea(readCoverageArea( child, xmlns)); } } return frame; } private TrackMessage readTrackMessage( final Element element, final Namespace xmlns ) { final TrackMessage msg = new TrackMessage(); msg.setUuid(UUID.randomUUID()); final List<Element> children = element.getChildren(); final Iterator<Element> childIter = children.iterator(); while (childIter.hasNext()) { final Element child = childIter.next(); final String childName = child.getName(); final String childValue = child.getValue(); if ("stanagVersion".equals(childName)) { msg.setFormatVersion(childValue); } else if ("messageSecurity".equals(childName)) { msg.setSecurity(readSecurity( child, xmlns)); } else if ("msgCreatedTime".equals(childName)) { msg.setMessageTime(DateStringToLong(childValue)); } else if ("senderId".equals(childName)) { msg.setSenderID(readIDdata( child, xmlns)); } else if ("tracks".equals(childName)) { msg.addTrackEvent(readTrackEvent( child, xmlns)); } } return msg; } private Security readSecurity( final Element element, final Namespace xmlns ) { final Security security = new Security(); final List<Element> children = element.getChildren(); final Iterator<Element> childIter = children.iterator(); while (childIter.hasNext()) { final Element child = childIter.next(); final String childName = child.getName(); final String childValue = child.getValue(); if ("securityClassification".equals(childName)) { try { security.setClassification(ClassificationLevel.valueOf(childValue)); } catch (final IllegalArgumentException iae) { LOGGER.warn( "Unable to set classification level", iae); security.setClassification(null); } } if ("securityPolicyName".equals(childName)) { security.setPolicyName(childValue); } if ("securityControlSystem".equals(childName)) { security.setControlSystem(childValue); } if ("securityDissemination".equals(childName)) { security.setDissemination(childValue); } if ("securityReleasability".equals(childName)) { security.setReleasability(childValue); } } return security; } private IDdata readIDdata( final Element element, final Namespace xmlns ) { final IDdata id = new IDdata(); final List<Element> children = element.getChildren(); final Iterator<Element> childIter = children.iterator(); while (childIter.hasNext()) { final Element child = childIter.next(); final String childName = child.getName(); final String childValue = child.getValue(); if ("stationID".equals(childName)) { id.setStationId(childValue); } else if ("nationality".equals(childName)) { id.setNationality(childValue); } } return id; } private TrackEvent readTrackEvent( final Element element, final Namespace xmlns ) { final TrackEvent trackEvent = new TrackEvent(); final List<Element> children = element.getChildren(); final Iterator<Element> childIter = children.iterator(); while (childIter.hasNext()) { final Element child = childIter.next(); final String childName = child.getName(); final String childValue = child.getValue(); if ("trackUUID".equals(childName)) { trackEvent.setUuid(childValue); } else if ("trackNumber".equals(childName)) { trackEvent.setTrackNumber(childValue); } else if ("trackStatus".equals(childName)) { try { trackEvent.setStatus(TrackStatus.valueOf(childValue)); } catch (final IllegalArgumentException iae) { LOGGER.warn( "Unable to set status", iae); trackEvent.setStatus(null); } } else if ("trackSecurity".equals(childName)) { trackEvent.setSecurity(readSecurity( child, xmlns)); } else if ("trackComment".equals(childName)) { trackEvent.setComment(childValue); } else if ("missionID".equals(childName)) { trackEvent.setMissionId(childValue); } else if ("exerciseIndicator".equals(childName)) { try { trackEvent.setExerciseIndicator(ExerciseIndicator.valueOf(childValue)); } catch (final IllegalArgumentException iae) { LOGGER.warn( "Unable to set exercise indicator", iae); trackEvent.setExerciseIndicator(null); } } else if ("simulationIndicator".equals(childName)) { try { trackEvent.setSimulationIndicator(SimulationIndicator.valueOf(childValue)); } catch (final IllegalArgumentException iae) { LOGGER.warn( "Unable to set simulation indicator", iae); trackEvent.setSimulationIndicator(null); } } else if ("items".equals(childName)) { final Namespace xsi = Namespace.getNamespace( "xsi", "http://www.w3.org/2001/XMLSchema-instance"); final Attribute xsitype = child.getAttribute( "type", xsi); if (xsitype != null) { if ("TrackPoint".equals(xsitype.getValue())) { trackEvent.addPoint(readTrackPoint( child, xmlns)); } else if ("TrackIdentityInformation".equals(xsitype.getValue())) { trackEvent.addIdentity(readTrackIdentity( child, xmlns)); } else if ("TrackClassificationInformation".equals(xsitype.getValue())) { trackEvent.addClassification(readTrackClassification( child, xmlns)); } else if ("TrackManagementInformation".equals(xsitype.getValue())) { trackEvent.addManagement(readTrackManagement( child, xmlns)); } else if ("VideoInformation".equals(xsitype.getValue())) { trackEvent.addMotionImagery(readMotionImagery( child, xmlns)); } else if ("ESMInformation".equals(xsitype.getValue())) { // TODO: ESM not implemented yet. } else if ("TrackLineageInformation".equals(xsitype.getValue())) { trackEvent.addTrackRelation(readLineageRelation( child, xmlns)); } else if ("MotionEventInformation".equals(xsitype.getValue())) { trackEvent.addMotionPoint(readMotionPoint( child, xmlns)); } } else { final TrackPoint point = readTrackPoint( child, xmlns); if (point != null) { trackEvent.addPoint(point); } } } } Track track = trackMap.get(trackEvent.getTrackNumber()); if (track == null) { track = new Track(); track.setUuid(trackEvent.getUuid()); // don't need to fully populate // the Track object trackMap.put( trackEvent.getTrackNumber(), track); trackStatsNumTracks++; } return trackEvent; } private TrackPoint readTrackPoint( final Element element, final Namespace xmlns ) { final TrackPoint trackPoint = new TrackPoint(); trackStatsNumDots++; final List<Element> children = element.getChildren(); final Iterator<Element> childIter = children.iterator(); while (childIter.hasNext()) { final Element child = childIter.next(); final String childName = child.getName(); final String childValue = child.getValue(); if ("trackItemUUID".equals(childName)) { trackPoint.uuid = childValue; } else if ("trackItemSecurity".equals(childName)) { trackPoint.security = readSecurity( child, xmlns); } else if ("trackItemTime".equals(childName)) { trackPoint.eventTime = DateStringToLong(childValue); } else if ("trackItemSource".equals(childName)) { trackPoint.trackItemSource = childValue; } else if ("trackItemComment".equals(childName)) { trackPoint.trackItemComment = childValue; } else if ("trackPointPosition".equals(childName)) { trackPoint.location = readGeodeticPosition( child, xmlns); } else if ("trackPointSpeed".equals(childName)) { try { trackPoint.speed = Double.parseDouble(childValue); } catch (final NumberFormatException nfe) { LOGGER.warn( "Unable to set speed", nfe); trackPoint.speed = null; } } else if ("motionEvent".equals(childName) && (childValue != null)) { trackPoint.motionEvent = childValue.trim(); } else if ("motionEventPosition".equals(childName)) { trackPoint.location = readGeodeticPosition( child, xmlns); } else if ("trackPointCourse".equals(childName)) { try { trackPoint.course = Double.parseDouble(childValue); } catch (final NumberFormatException nfe) { LOGGER.warn( "Unable to set course", nfe); trackPoint.course = null; } } else if ("trackPointType".equals(childName)) { try { trackPoint.trackPointType = TrackPointType.valueOf(childValue); } catch (final IllegalArgumentException iae) { LOGGER.warn( "Unable to set track point type", iae); trackPoint.trackPointType = null; } } else if ("trackPointSource".equals(childName)) { trackPoint.trackPointSource = ModalityType.fromString(childValue); } else if ("trackPointObjectMask".equals(childName)) { trackPoint.objectMask = readArea( child, xmlns); } else if ("TrackPointDetail".equals(childName)) { trackPoint.detail = readTrackPointDetail( child, xmlns); } } return trackPoint; } private MotionEventPoint readMotionPoint( final Element element, final Namespace xmlns ) { final MotionEventPoint trackPoint = new MotionEventPoint(); // trackStatsNumDots++; final List<Element> children = element.getChildren(); final Iterator<Element> childIter = children.iterator(); while (childIter.hasNext()) { final Element child = childIter.next(); final String childName = child.getName(); final String childValue = child.getValue(); if ("trackItemUUID".equals(childName)) { trackPoint.uuid = childValue; } else if ("trackItemSecurity".equals(childName)) { trackPoint.security = readSecurity( child, xmlns); } else if ("trackItemTime".equals(childName)) { trackPoint.eventTime = DateStringToLong(childValue); } else if ("trackItemSource".equals(childName)) { trackPoint.trackItemSource = childValue; } else if ("trackItemComment".equals(childName)) { trackPoint.trackItemComment = childValue; } else if ("trackPointPosition".equals(childName)) { trackPoint.location = readGeodeticPosition( child, xmlns); } else if ("trackPointSpeed".equals(childName)) { try { trackPoint.speed = Double.parseDouble(childValue); } catch (final NumberFormatException nfe) { LOGGER.warn( "Unable to set speed", nfe); trackPoint.speed = null; } } else if ("motionEvent".equals(childName) && (childValue != null)) { trackPoint.motionEvent = childValue.trim(); } else if ("motionEventEndTime".equals(childName) && (childValue != null)) { trackPoint.eventEndTime = DateStringToLong(childValue); } else if ("motionEventPosition".equals(childName)) { trackPoint.location = readGeodeticPosition( child, xmlns); } else if ("trackPointCourse".equals(childName)) { try { trackPoint.course = Double.parseDouble(childValue); } catch (final NumberFormatException nfe) { LOGGER.warn( "Unable to set course", nfe); trackPoint.course = null; } } else if ("trackPointType".equals(childName)) { try { trackPoint.trackPointType = TrackPointType.valueOf(childValue); } catch (final IllegalArgumentException iae) { LOGGER.warn( "Unable to set track point type", iae); trackPoint.trackPointType = null; } } else if ("trackPointSource".equals(childName)) { try { trackPoint.trackPointSource = ModalityType.valueOf(childValue); } catch (final IllegalArgumentException iae) { LOGGER.warn( "Unable to set track point source", iae); trackPoint.trackPointSource = null; } } else if ("trackPointObjectMask".equals(childName)) { trackPoint.objectMask = readArea( child, xmlns); } else if ("TrackPointDetail".equals(childName)) { trackPoint.detail = readTrackPointDetail( child, xmlns); } } return trackPoint; } private TrackIdentity readTrackIdentity( final Element element, final Namespace xmlns ) { final TrackIdentity trackIdentity = new TrackIdentity(); final List<Element> children = element.getChildren(); final Iterator<Element> childIter = children.iterator(); while (childIter.hasNext()) { final Element child = childIter.next(); final String childName = child.getName(); final String childValue = child.getValue(); if ("identity".equals(childName)) { try { trackIdentity.identity = Identity.valueOf(childValue); } catch (final IllegalArgumentException iae) { LOGGER.warn( "Unable to set identity", iae); trackIdentity.identity = null; } } // TODO: Track Identity } return trackIdentity; } private TrackClassification readTrackClassification( final Element element, final Namespace xmlns ) { final TrackClassification trackClassification = new TrackClassification(); final List<Element> children = element.getChildren(); final Iterator<Element> childIter = children.iterator(); while (childIter.hasNext()) { final Element child = childIter.next(); final String childName = child.getName(); final String childValue = child.getValue(); if ("trackItemUUID".equals(childName)) { try { trackClassification.setUuid(UUID.fromString(childValue)); } catch (final IllegalArgumentException iae) { LOGGER.warn( "Unable to set uuid", iae); trackClassification.setUuid(null); } } else if ("trackItemSecurity".equals(childName)) { trackClassification.setSecurity(readSecurity( child, xmlns)); } else if ("trackItemTime".equals(childName)) { trackClassification.setTime(DateStringToLong(childValue)); } else if ("trackItemSource".equals(childName)) { trackClassification.setSource(childValue); } else if ("classification".equals(childName)) { trackClassification.classification = ObjectClassification.fromString(childValue); } else if ("classificationCredibility".equals(childName)) { trackClassification.credibility = readClassificationCredibility( child, xmlns); } else if ("numObjects".equals(childName)) { trackClassification.setNumObjects(Integer.parseInt(child.getText())); } } return trackClassification; } private TrackManagement readTrackManagement( final Element element, final Namespace xmlns ) { final TrackManagement trackManagement = new TrackManagement(); final List<Element> children = element.getChildren(); final Iterator<Element> childIter = children.iterator(); while (childIter.hasNext()) { final Element child = childIter.next(); final String childName = child.getName(); final String childValue = child.getValue(); if ("trackItemUUID".equals(childName)) { try { trackManagement.setUuid(UUID.fromString(childValue)); } catch (final IllegalArgumentException iae) { LOGGER.warn( "Unable to set uuid", iae); trackManagement.setUuid(null); } } else if ("trackItemSecurity".equals(childName)) { trackManagement.setSecurity(readSecurity( child, xmlns)); } else if ("trackItemTime".equals(childName)) { trackManagement.setTime(DateStringToLong(childValue)); } else if ("trackItemSource".equals(childName)) { trackManagement.setSource(childValue); } else if ("trackItemComment".equals(childName)) { trackManagement.setComment(childValue); } else if ("trackProductionArea".equals(childName)) { trackManagement.area = readArea( child, xmlns); } else if ("trackSource".equals(childName)) { try { trackManagement.sourceModality = ModalityType.valueOf(childValue); } catch (final IllegalArgumentException iae) { LOGGER.warn( "Unable to set source modality", iae); trackManagement.sourceModality = null; } } else if ("trackEnvironment".equals(childName)) { try { trackManagement.environment = TrackEnvironment.valueOf(childValue); } catch (final IllegalArgumentException iae) { LOGGER.warn( "Unable to set environment", iae); trackManagement.environment = null; } } else if ("trackQuality".equals(childName)) { try { trackManagement.quality = Integer.parseInt(childValue); } catch (final NumberFormatException nfe) { trackManagement.quality = 0; } } else if ("trackerID".equals(childName)) { final IDdata id = readIDdata( child, xmlns); trackManagement.stationId = id.getStationId(); trackManagement.nationality = id.getNationality(); } else if ("trackerType".equals(childName)) { try { trackManagement.trackerType = TrackerType.valueOf(childValue); } catch (final IllegalArgumentException iae) { LOGGER.warn( "Unable to set tracker type", iae); trackManagement.trackerType = null; } } else if ("alertIndicator".equals(childName)) { try { trackManagement.alertIndicator = Boolean.parseBoolean(childValue); } catch (final IllegalArgumentException iae) { LOGGER.warn( "Unable to set alert indicator", iae); trackManagement.alertIndicator = false; } } } return trackManagement; } private MotionImagery readMotionImagery( final Element element, final Namespace xmlns ) { final MotionImagery motionImagery = new MotionImagery(); final List<Element> children = element.getChildren(); final Iterator<Element> childIter = children.iterator(); while (childIter.hasNext()) { final Element child = childIter.next(); final String childName = child.getName(); final String childValue = child.getValue(); if ("trackItemUUID".equals(childName)) { try { motionImagery.setUuid(UUID.fromString(childValue)); } catch (final IllegalArgumentException iae) { LOGGER.warn( "Unable to set uuid", iae); motionImagery.setUuid(null); } } else if ("trackItemSecurity".equals(childName)) { motionImagery.setSecurity(readSecurity( child, xmlns)); } else if ("trackItemTime".equals(childName)) { motionImagery.setTime(DateStringToLong(childValue)); } else if ("trackItemSource".equals(childName)) { motionImagery.setSource(childValue); } else if ("trackItemComment".equals(childName)) { motionImagery.setComment(childValue); } else if ("band".equals(childName)) { try { motionImagery.band = SymbolicSpectralRange.valueOf(childValue); } catch (final IllegalArgumentException iae) { LOGGER.warn( "Unable to set band value", iae); motionImagery.band = null; } } else if ("imageReference".equals(childName)) { motionImagery.imageReference = childValue; } else if ("imageChip".equals(childName)) { motionImagery.imageChip = child.getText(); } else if ("frameNumber".equals(childName)) { motionImagery.frameNumber = Integer.parseInt(child.getText()); } else if ("pixelRow".equals(childName)) { motionImagery.pixelRow = Integer.parseInt(child.getText()); } else if ("pixelColumn".equals(childName)) { motionImagery.pixelColumn = Integer.parseInt(child.getText()); } } return motionImagery; } private LineageRelation readLineageRelation( final Element element, final Namespace xmlns ) { final LineageRelation relation = new LineageRelation(); final List<Element> children = element.getChildren(); final Iterator<Element> childIter = children.iterator(); while (childIter.hasNext()) { final Element child = childIter.next(); final String childName = child.getName(); final String childValue = child.getValue(); if ("relations".equals(childName)) { // TODO: TrackLineageInformation / LineageRelation } } return relation; } private ClassificationCredibility readClassificationCredibility( final Element element, final Namespace xmlns ) { final ClassificationCredibility credibility = new ClassificationCredibility(); final List<Element> children = element.getChildren(); final Iterator<Element> childIter = children.iterator(); while (childIter.hasNext()) { final Element child = childIter.next(); final String childName = child.getName(); final String childValue = child.getValue(); if ("valueConfidence".equals(childName)) { try { credibility.setValueConfidence(Integer.parseInt(childValue)); } catch (final NumberFormatException nfe) {} } else if ("sourceReliability".equals(childName)) { try { credibility.setSourceReliability(Integer.parseInt(childValue)); } catch (final NumberFormatException nfe) {} } } return credibility; } private GeodeticPosition readGeodeticPosition( final Element element, final Namespace xmlns ) { final GeodeticPosition pos = new GeodeticPosition(); final List<Element> children = element.getChildren(); final Iterator<Element> childIter = children.iterator(); while (childIter.hasNext()) { final Element child = childIter.next(); final String childName = child.getName(); final String childValue = child.getValue(); if ("latitude".equals(childName)) { try { pos.latitude = Double.parseDouble(childValue); } catch (final NumberFormatException nfe) { pos.latitude = null; } } else if ("longitude".equals(childName)) { try { pos.longitude = Double.parseDouble(childValue); } catch (final NumberFormatException nfe) { pos.longitude = null; } } else if ("elevation".equals(childName)) { try { pos.elevation = Double.parseDouble(childValue); } catch (final NumberFormatException nfe) { pos.elevation = null; } } } return pos; } private Area readArea( final Element element, final Namespace xmlns ) { final Area area = new Area(); final List<Element> children = element.getChildren(); final Iterator<Element> childIter = children.iterator(); while (childIter.hasNext()) { final Element child = childIter.next(); final String childName = child.getName(); final String childValue = child.getValue(); if ("xxx".equals(childName)) { // area.setXXX(childValue); // TODO: Area , CircularArea, PolygonArea, etc... } } return area; } private Area readCoverageArea( final Element element, final Namespace xmlns ) { final Area area = new Area(); final List<Element> children = element.getChildren(); final Iterator<Element> childIter = children.iterator(); while (childIter.hasNext()) { final Element child = childIter.next(); final String childName = child.getName(); final String childValue = child.getValue(); if ("areaBoundaryPoints".equals(childName)) { GeodeticPosition pos = readGeodeticPosition( child, xmlns); area.getPoints().add( pos); } } return area; } private TrackPointDetail readTrackPointDetail( final Element element, final Namespace xmlns ) { final Namespace xsi = Namespace.getNamespace( "xsi", "http://www.w3.org/2001/XMLSchema-instance"); final TrackPointDetail detail = new TrackPointDetail(); final List<Element> children = element.getChildren(); final Iterator<Element> childIter = children.iterator(); while (childIter.hasNext()) { final Element child = childIter.next(); final String childName = child.getName(); final String childValue = child.getValue(); if ("pointDetailPosition".equals(childName)) { // check which type... final Attribute xsitype = child.getAttribute( "type", xsi); if (xsitype != null) { if ("GeodeticPosition".equals(xsitype.getValue())) { detail.location = readGeodeticPosition( child, xmlns); } else if ("LocalCartesianPosition".equals(xsitype.getValue())) { // TODO: Add support for reading LocalCartesianPosition } } else { try { final GeodeticPosition geoPos = readGeodeticPosition( child, xmlns); if (geoPos != null) { detail.location = geoPos; } } catch (final Exception e) { LOGGER.error( "Could not identify TrackPoint position type", e); } } } else if ("pointDetailVelocity".equals(childName)) { final Attribute xsitype = child.getAttribute( "type", xsi); if (xsitype != null) { if ("LocalCartesianVelocity".equals(xsitype.getValue())) { final Double[] velCoords = readLocalCartesianVelocity(child); detail.velocityX = velCoords[0]; detail.velocityY = velCoords[1]; detail.velocityZ = velCoords[2]; } } else { try { final Double[] velCoords = readLocalCartesianVelocity(child); detail.velocityX = velCoords[0]; detail.velocityY = velCoords[1]; detail.velocityZ = velCoords[2]; } catch (final Exception e) { LOGGER.error( "Could not identify TrackPoint velocity", e); } } } else if ("pointDetailAcceleration".equals(childName)) { final Attribute xsitype = child.getAttribute( "type", xsi); if (xsitype != null) { if ("LocalCartesianAcceleration".equals(xsitype.getValue())) { final Double[] accelCoords = readLocalCartesianAccel(child); detail.accelerationX = accelCoords[0]; detail.accelerationY = accelCoords[1]; detail.accelerationZ = accelCoords[2]; } } else { try { final Double[] accelCoords = readLocalCartesianAccel(child); detail.accelerationX = accelCoords[0]; detail.accelerationY = accelCoords[1]; detail.accelerationZ = accelCoords[2]; } catch (final Exception e) { LOGGER.error( "Could not identify TrackPoint velocity", e); } } } else if ("pointDetailCovarianceMatrix".equals(childName)) { detail.covarianceMatrix = readCovarianceMatrix( child, xmlns); } } return detail; } private Double[] readLocalCartesianVelocity( final Element child ) { final Double[] velCoords = new Double[3]; final List<Element> grandchildren = child.getChildren(); final Iterator<Element> grandchildIter = grandchildren.iterator(); while (grandchildIter.hasNext()) { final Element grandchild = grandchildIter.next(); final String grandchildName = grandchild.getName(); final String grandchildValue = grandchild.getValue(); if ("velx".equals(grandchildName)) { try { velCoords[0] = Double.parseDouble(grandchildValue); } catch (final NumberFormatException nfe) { velCoords[0] = null; } } else if ("vely".equals(grandchildName)) { try { velCoords[1] = Double.parseDouble(grandchildValue); } catch (final NumberFormatException nfe) { velCoords[1] = null; } } else if ("velz".equals(grandchildName)) { try { velCoords[2] = Double.parseDouble(grandchildValue); } catch (final NumberFormatException nfe) { velCoords[2] = null; } } } return velCoords; } private Double[] readLocalCartesianAccel( final Element child ) { final Double[] accelCoords = new Double[3]; final List<Element> grandchildren = child.getChildren(); final Iterator<Element> grandchildIter = grandchildren.iterator(); while (grandchildIter.hasNext()) { final Element grandchild = grandchildIter.next(); final String grandchildName = grandchild.getName(); final String grandchildValue = grandchild.getValue(); if ("accx".equals(grandchildName)) { try { accelCoords[0] = Double.parseDouble(grandchildValue); } catch (final NumberFormatException nfe) { accelCoords[0] = null; } } else if ("accy".equals(grandchildName)) { try { accelCoords[1] = Double.parseDouble(grandchildValue); } catch (final NumberFormatException nfe) { accelCoords[1] = null; } } else if ("accz".equals(grandchildName)) { try { accelCoords[2] = Double.parseDouble(grandchildValue); } catch (final NumberFormatException nfe) { accelCoords[2] = null; } } } return accelCoords; } private CovarianceMatrix readCovarianceMatrix( final Element element, final Namespace xmlns ) { final CovarianceMatrix matrix = new CovarianceMatrix(); final List<Element> children = element.getChildren(); final Iterator<Element> childIter = children.iterator(); while (childIter.hasNext()) { final Element child = childIter.next(); final String childName = child.getName(); final String childValue = child.getValue(); if ("covPosxPosx".equals(childName)) { try { matrix.covPosXPosX = Double.parseDouble(childValue); } catch (final NumberFormatException nfe) { matrix.covPosXPosX = null; } } else if ("covPosyPosy".equals(childName)) { try { matrix.covPosYPosY = Double.parseDouble(childValue); } catch (final NumberFormatException nfe) { matrix.covPosYPosY = null; } } else if ("covPoszPosz".equals(childName)) { try { matrix.covPosZPosZ = Double.parseDouble(childValue); } catch (final NumberFormatException nfe) { matrix.covPosZPosZ = null; } } else if ("covPosxPosy".equals(childName)) { try { matrix.covPosXPosY = Double.parseDouble(childValue); } catch (final NumberFormatException nfe) { matrix.covPosXPosY = null; } } else if ("covPosxPosz".equals(childName)) { try { matrix.covPosXPosZ = Double.parseDouble(childValue); } catch (final NumberFormatException nfe) { matrix.covPosXPosZ = null; } } else if ("covPosyPosz".equals(childName)) { try { matrix.covPosYPosZ = Double.parseDouble(childValue); } catch (final NumberFormatException nfe) { matrix.covPosYPosZ = null; } } else if ("covVelxVelx".equals(childName)) { try { matrix.covVelXVelX = Double.parseDouble(childValue); } catch (final NumberFormatException nfe) { matrix.covVelXVelX = null; } } else if ("covVelyVely".equals(childName)) { try { matrix.covVelYVelY = Double.parseDouble(childValue); } catch (final NumberFormatException nfe) { matrix.covVelYVelY = null; } } else if ("covVelzVelz".equals(childName)) { try { matrix.covVelZVelZ = Double.parseDouble(childValue); } catch (final NumberFormatException nfe) { matrix.covVelZVelZ = null; } } else if ("covPosxVelx".equals(childName)) { try { matrix.covPosXVelX = Double.parseDouble(childValue); } catch (final NumberFormatException nfe) { matrix.covPosXVelX = null; } } else if ("covPosxVely".equals(childName)) { try { matrix.covPosXVelY = Double.parseDouble(childValue); } catch (final NumberFormatException nfe) { matrix.covPosXVelY = null; } } else if ("covPosxVelz".equals(childName)) { try { matrix.covPosXVelZ = Double.parseDouble(childValue); } catch (final NumberFormatException nfe) { matrix.covPosXVelZ = null; } } else if ("covPosyVelx".equals(childName)) { try { matrix.covPosYVelX = Double.parseDouble(childValue); } catch (final NumberFormatException nfe) { matrix.covPosYVelX = null; } } else if ("covPosyVely".equals(childName)) { try { matrix.covPosYVelY = Double.parseDouble(childValue); } catch (final NumberFormatException nfe) { matrix.covPosYVelY = null; } } else if ("covPosyVelz".equals(childName)) { try { matrix.covPosYVelZ = Double.parseDouble(childValue); } catch (final NumberFormatException nfe) { matrix.covPosYVelZ = null; } } else if ("covPoszVelx".equals(childName)) { try { matrix.covPosZVelX = Double.parseDouble(childValue); } catch (final NumberFormatException nfe) { matrix.covPosZVelX = null; } } else if ("covPoszVely".equals(childName)) { try { matrix.covPosZVelY = Double.parseDouble(childValue); } catch (final NumberFormatException nfe) { matrix.covPosZVelY = null; } } else if ("covPoszVelz".equals(childName)) { try { matrix.covPosZVelZ = Double.parseDouble(childValue); } catch (final NumberFormatException nfe) { matrix.covPosZVelZ = null; } } else if ("covVelxVely".equals(childName)) { try { matrix.covVelXVelY = Double.parseDouble(childValue); } catch (final NumberFormatException nfe) { matrix.covVelXVelY = null; } } else if ("covVelxVelz".equals(childName)) { try { matrix.covVelXVelZ = Double.parseDouble(childValue); } catch (final NumberFormatException nfe) { matrix.covVelXVelZ = null; } } else if ("covVelyVelz".equals(childName)) { try { matrix.covVelYVelZ = Double.parseDouble(childValue); } catch (final NumberFormatException nfe) { matrix.covVelYVelZ = null; } } } return matrix; } private long DateStringToLong( String dateString ) { // matches on ".??????Z" and removes the last three ??? (microseconds) dateString = dateString.replaceAll( "(\\.\\d{3})\\d+[Z]", "$1Z"); Date date = parseHelper( dateString, "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); if (date == null) { date = parseHelper( dateString, "yyyy-MM-dd'T'HH:mm:ss.SSS"); if (date == null) { date = parseHelper( dateString, "yyyy-MM-dd'T'HH:mm:ss'Z'"); if (date == null) { date = parseHelper( dateString, "yyyy-MM-dd'T'HH:mm:ss"); if (date == null) { return 0; } } } } return date.getTime(); } private Date parseHelper( final String dateString, final String format ) { final DateFormat parser = new SimpleDateFormat( format); parser.setTimeZone(TimeZone.getTimeZone("GMT")); try { return parser.parse(dateString); } catch (final ParseException e) { return null; } } }