/* * Copyright (c) 2014 Oculus Info Inc. http://www.oculusinfo.com/ * * Released under the MIT License. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package com.oculusinfo.annotation.util; import com.oculusinfo.annotation.AnnotationBin; import com.oculusinfo.annotation.AnnotationData; import com.oculusinfo.annotation.AnnotationTile; import com.oculusinfo.annotation.index.AnnotationIndexer; import com.oculusinfo.binning.BinIndex; import com.oculusinfo.binning.TileIndex; import com.oculusinfo.binning.impl.DenseTileData; import com.oculusinfo.factory.util.Pair; import org.json.JSONArray; import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.*; public class AnnotationUtil { private static final Logger LOGGER = LoggerFactory.getLogger( AnnotationUtil.class ); public static void printData( Map<BinIndex, List<AnnotationData<?>>> dataMap ) { for ( List<AnnotationData<?>> annotations : dataMap.values() ) { printData( annotations ); } } public static void printData( List<AnnotationData<?>> annotations ) { for ( AnnotationData<?> annotation : annotations ) { try { LOGGER.debug( annotation.toJSON().toString( 4 ) ); } catch ( Exception e ) { e.printStackTrace(); } } } public static void printTiles( List<AnnotationTile> tiles ) { for ( AnnotationTile tile : tiles ) { try { LOGGER.debug( tileToJSON( tile ).toString( 4 ) ); } catch ( Exception e ) { e.printStackTrace(); } } } public static boolean compareData( List<AnnotationData<?>> as, List<AnnotationData<?>> bs ) { for ( AnnotationData<?> a : as ) { int foundCount = 0; for ( AnnotationData<?> b : bs ) { if ( compareData(a, b ) ) { foundCount++; } } if ( foundCount != 1 ) { LOGGER.debug( "Data lists do not match" ); return false; } } return true; } public static boolean compareTiles( List<AnnotationTile> as, List< AnnotationTile > bs ) { for ( AnnotationTile a : as ) { int foundCount = 0; for ( AnnotationTile b : bs ) { if ( compareTiles( a, b, false ) ) { foundCount++; } } if ( foundCount != 1 ) { LOGGER.debug( "Tile lists do not match" ); return false; } } return true; } public static <T> boolean compareAttributes( T a, T b ) { if ( a == null || b == null ) { return ( a == b ); } else { return a.equals( b ); } } public static boolean compareData( AnnotationData<?> a, AnnotationData<?> b ) { if ( !a.getUUID().equals( b.getUUID() ) ) { LOGGER.debug( "UUID are not equal" ); return false; } if ( !compareAttributes( a.getX(), b.getX() ) ) { LOGGER.debug( "X values are not equal" ); return false; } if ( !compareAttributes( a.getY(), b.getY() ) ) { LOGGER.debug( "Y values are not equal" ); return false; } if ( !compareAttributes( a.getX0(), b.getX0() ) ) { LOGGER.debug( "X0 values are not equal" ); return false; } if ( !compareAttributes( a.getY0(), b.getY0() ) ) { LOGGER.debug( "Y0 values are not equal" ); return false; } if ( !compareAttributes( a.getX1(), b.getX1() ) ) { LOGGER.debug( "X1 values are not equal" ); return false; } if ( !compareAttributes( a.getY1(), b.getY1() ) ) { LOGGER.debug( "Y1 values are not equal" ); return false; } if ( !a.getLevel().equals( b.getLevel() ) ) { LOGGER.debug( "Level values are not equal" ); return false; } if ( !a.getData().toString().equals( b.getData().toString() ) ) { LOGGER.debug( "Data objects are not equal" ); return false; } return true; } public static boolean compareTiles( AnnotationTile a, AnnotationTile b, boolean verbose ) { List<Pair<String, Long>> aReferences = a.getAllCertificates(); List<Pair<String, Long>> bReferences = b.getAllCertificates(); if ( !a.getDefinition().equals( b.getDefinition() ) ) { LOGGER.debug( "Bin indices are not equal"); return false; } if ( aReferences.size() != bReferences.size() ) { LOGGER.debug( "Reference counts are not equal"); return false; } for ( Pair<String, Long> aRef : aReferences ) { int foundCount = 0; for ( Pair<String, Long> bRef : bReferences ) { if ( aRef.equals( bRef ) ) { foundCount++; } } if ( foundCount != 1 ) { LOGGER.debug( "Reference lists are not equal"); return false; } } return true; } public static List<TileIndex> tilesToIndices( List< AnnotationTile > tiles ) { List<TileIndex> indices = new ArrayList<>(); for ( AnnotationTile tile : tiles ) { indices.add( tile.getDefinition() ); } return indices; } public static List<Pair<String, Long>> dataToIndices( List<AnnotationData<?>> data ) { List<Pair<String, Long>> indices = new ArrayList<>(); for ( AnnotationData<?> d : data ) { indices.add( d.getCertificate() ); } return indices; } public static JSONObject certificateToJSON( Pair<String, Long> certificate ) { JSONObject json = new JSONObject(); try { json.put( "uuid", certificate.getFirst() ); json.put( "timestamp", certificate.getSecond().toString() ); } catch ( Exception e ) { e.printStackTrace(); } return json; } static public Pair<String, Long> getCertificateFromJSON( JSONObject json ) throws IllegalArgumentException { try { UUID uuid = UUID.fromString( json.getString("uuid") ); Long timestamp = Long.parseLong( json.getString("timestamp") ); return new Pair<>( uuid.toString(), timestamp ); } catch ( Exception e ) { throw new IllegalArgumentException( e ); } } public static AnnotationBin getBinFromJSON( JSONObject json ) throws IllegalArgumentException { try { Map<String, List<Pair<String, Long>>> certificates = new LinkedHashMap<>(); Iterator<?> groups = json.keys(); while( groups.hasNext() ){ String group = (String)groups.next(); if( json.get(group) instanceof JSONArray ) { JSONArray jsonCertificates = json.getJSONArray(group); List<Pair<String, Long>> certificateList = new LinkedList<>(); for (int i=0; i<jsonCertificates.length(); i++) { JSONObject jsonRef = jsonCertificates.getJSONObject( i ); certificateList.add( getCertificateFromJSON( jsonRef ) ); } certificates.put( group, certificateList ); } } return new AnnotationBin( certificates ); } catch ( Exception e ) { throw new IllegalArgumentException( e ); } } static public JSONObject binToJSON( AnnotationBin bin ) { JSONObject binJSON = new JSONObject(); try { // for each group group in a bin for (Map.Entry<String, List<Pair<String, Long>>> certificateEntry : bin.getData().entrySet() ) { String group = certificateEntry.getKey(); List<Pair<String, Long>> certificates = certificateEntry.getValue(); JSONArray certificateJSON = new JSONArray(); for ( Pair<String, Long> certificate : certificates ) { certificateJSON.put( certificateToJSON( certificate ) ); } // add group to bin json object binJSON.put( group, certificateJSON ); } } catch ( Exception e ) { e.printStackTrace(); } return binJSON; } static public AnnotationTile getTileFromJSON( JSONObject json ) throws IllegalArgumentException { try { TileIndex index = new TileIndex( json.getInt("level"), json.getInt("x"), json.getInt("y"), AnnotationIndexer.NUM_BINS, AnnotationIndexer.NUM_BINS ); // create tile with empty bins DenseTileData<AnnotationBin> tile = new DenseTileData<>( index ); // for all binkeys Iterator<?> binKeys = json.keys(); while( binKeys.hasNext() ) { String binKey = (String)binKeys.next(); if( json.get(binKey) instanceof JSONObject ){ JSONObject bin = (JSONObject)json.get(binKey); BinIndex binIndex = BinIndex.fromString( binKey ); tile.setBin( binIndex.getX(), binIndex.getY(), getBinFromJSON( bin )); } } return new AnnotationTile( tile.getDefinition(), tile.getData() ); } catch ( Exception e ) { throw new IllegalArgumentException( e ); } } static public JSONObject tileToJSON( AnnotationTile tile ) { JSONObject tileJSON = new JSONObject(); try { tileJSON.put("level", tile.getDefinition().getLevel() ); tileJSON.put("x", tile.getDefinition().getX() ); tileJSON.put("y", tile.getDefinition().getY() ); for (int i=0; i<tile.getDefinition().getXBins(); i++ ) { for (int j=0; j<tile.getDefinition().getYBins(); j++ ) { AnnotationBin bin = tile.getBin(i, j); if ( bin != null) { // add bin object to tile tileJSON.put( new BinIndex(i, j).toString(), binToJSON( bin ) ); } } } } catch ( Exception e ) { e.printStackTrace(); } return tileJSON; } }