Input: Cache the DMR . What it really does is cache the DMR and write it at the point where it is needed ; either in close () if writing the DMR only or in writeChunk () if writing data as well . [CODESPLIT] public void cacheDMR ( String dmr ) throws IOException { if ( state != State . INITIAL ) throw new DapException ( "Attempt to write DMR twice" ) ; if ( dmr == null ) throw new DapException ( "Attempt to write empty DMR" ) ; // Strip off any trailing sequence of CR or LF. int len = dmr . length ( ) ; while ( len > 0 ) { char c = dmr . charAt ( len - 1 ) ; if ( c != ' ' && c != ' ' ) break ; len -- ; } if ( dmr . length ( ) == 0 ) throw new DapException ( "Attempt to write empty DMR" ) ; dmr = dmr . substring ( 0 , len ) + DapUtil . CRLF ; // Prepend the <?xml...?> prefix dmr = XMLDOCUMENTHEADER + "\n" + dmr ; // Convert the dmr to UTF-8 and then to byte[] this . dmr8 = DapUtil . extract ( DapUtil . UTF8 . encode ( dmr ) ) ; state = State . DMR ; }


Input: Output the specifiedd DMR or DSR or ... but xml only . [CODESPLIT] void sendDXR ( byte [ ] dxr8 ) throws IOException { if ( dxr8 == null || dxr8 . length == 0 ) return ; // do nothing if ( mode == RequestMode . DMR || mode == RequestMode . DSR ) { state = State . END ; } else { //mode == DATA // Prefix with chunk header int flags = DapUtil . CHUNK_DATA ; if ( this . writeorder == ByteOrder . LITTLE_ENDIAN ) flags |= DapUtil . CHUNK_LITTLE_ENDIAN ; chunkheader ( dxr8 . length , flags , this . header ) ; // write the header output . write ( DapUtil . extract ( this . header ) ) ; state = State . DATA ; } // write the DXR output . write ( dxr8 ) ; output . flush ( ) ; }


Input: Write an error chunk . If mode == DMR then replaces the dmr else reset the current chunk thus losing any partial write . [CODESPLIT] public void writeError ( int httpcode , String msg , String cxt , String other ) throws IOException { dmr8 = null ; ErrorResponse response = new ErrorResponse ( httpcode , msg , cxt , other ) ; String errorbody = response . buildXML ( ) ; // Convert the error body into utf8 then to byte[] byte [ ] errbody8 = DapUtil . extract ( DapUtil . UTF8 . encode ( errorbody ) ) ; if ( mode == RequestMode . DMR ) { sendDXR ( errbody8 ) ; } else { //mode == DATA // clear any partial chunk chunk . clear ( ) ; // create an error header int flags = DapUtil . CHUNK_ERROR | DapUtil . CHUNK_END ; chunkheader ( errbody8 . length , flags , header ) ; output . write ( DapUtil . extract ( header ) ) ; output . write ( errbody8 ) ; output . flush ( ) ; } state = State . ERROR ; }


Input: Write out the current chunk ( with given set of flags ) . [CODESPLIT] void writeChunk ( int flags ) throws IOException { // If flags indicate CHUNK_END // and amount to write is zero, // go ahead and write the zero size chunk. if ( chunk == null ) chunk = ByteBuffer . allocate ( maxbuffersize ) ; int buffersize = chunk . position ( ) ; chunkheader ( buffersize , flags , header ) ; // output the header followed by the data (if any) // Zero size chunk is ok. output . write ( DapUtil . extract ( header ) ) ; if ( buffersize > 0 ) output . write ( chunk . array ( ) , 0 , buffersize ) ; chunk . clear ( ) ; // reset }


Input: Closes this output stream and releases any system resources associated with this stream . Except the underlying stream is not actually closed ; that is left to the servlet level [CODESPLIT] public void close ( ) throws IOException { if ( closed ) return ; closed = true ; if ( dmr8 != null ) { sendDXR ( dmr8 ) ; dmr8 = null ; } if ( mode == RequestMode . DMR ) return ; // only DMR should be sent // If there is no partial chunk to write then // we are done; else verify we can write and write the last // chunk; => multiple closes are ok. if ( chunk == null || chunk . position ( ) == 0 ) return ; // There is data left to write. verifystate ( ) ; // are we in a state supporting data write? // Force out the current chunk (might be empty) // but do not close the underlying output stream state = State . DATA ; // pretend int flags = DapUtil . CHUNK_END ; writeChunk ( flags ) ; state = State . END ; this . output . flush ( ) ; // Do not close if ( this . saveoutput != null ) { // write to true output target this . saveoutput . write ( ( ( ByteArrayOutputStream ) this . output ) . toByteArray ( ) ) ; } }


Input: Overload flush to also write out the DMR [CODESPLIT] @ Override public void flush ( ) throws IOException { if ( mode == RequestMode . DMR ) return ; // leave to close() to do this if ( dmr8 != null ) { sendDXR ( dmr8 ) ; dmr8 = null ; } }


Input: Writes len bytes from the specified byte array starting at offset off to this output stream . <p > If this write fills up the chunk buffer then write out the buffer and put the remaining bytes into the reset buffer . [CODESPLIT] @ Override public void write ( byte [ ] b , int off , int len ) throws IOException { verifystate ( ) ; if ( writecount + len >= writelimit ) throw new DapException ( "Attempt to write too much data: limit=" + writecount + len ) . setCode ( DapCodes . SC_REQUESTED_RANGE_NOT_SATISFIABLE ) ; if ( chunk == null ) chunk = ByteBuffer . allocate ( maxbuffersize ) . order ( getWriteOrder ( ) ) ; if ( state == State . DMR ) { chunk . clear ( ) ; // reset state = State . DATA ; } assert ( state == State . DATA ) ; if ( b . length < off + len ) throw new BufferUnderflowException ( ) ; int left = len ; int offset = off ; while ( left > 0 ) { int avail = chunk . remaining ( ) ; do { if ( avail == 0 ) { writeChunk ( DapUtil . CHUNK_DATA ) ; avail = chunk . remaining ( ) ; } int towrite = ( left < avail ? left : avail ) ; chunk . put ( b , off , towrite ) ; left -= towrite ; avail -= towrite ; } while ( left > 0 ) ; } writecount += len ; }


Input: needed for constructCopy [CODESPLIT] @ Override public ProjectionImpl constructCopy ( ) { ProjectionImpl result = ( saveParams == null ) ? new UtmProjection ( getZone ( ) , isNorth ( ) ) : new UtmProjection ( saveParams . a , saveParams . f , getZone ( ) , isNorth ( ) ) ; result . setDefaultMapArea ( defaultMapArea ) ; result . setName ( name ) ; return result ; }


Input: Convert a LatLonPoint to projection coordinates [CODESPLIT] public ProjectionPoint latLonToProj ( LatLonPoint latLon , ProjectionPointImpl result ) { double fromLat = latLon . getLatitude ( ) ; double fromLon = latLon . getLongitude ( ) ; return convert2xy . latLonToProj ( fromLat , fromLon , result ) ; }


Input: Convert projection coordinates to a LatLonPoint Note : a new object is not created on each call for the return value . [CODESPLIT] public LatLonPoint projToLatLon ( ProjectionPoint world , LatLonPointImpl result ) { return convert2latlon . projToLatLon ( world . getX ( ) , world . getY ( ) , result ) ; }


Input: / * roszelld@usgs . gov m transforming coordinates ( which are in UTM Zone 17N projection ) to lat / lon . [CODESPLIT] public static void main ( String arg [ ] ) { UtmProjection utm = new UtmProjection ( 17 , true ) ; LatLonPoint ll = utm . projToLatLon ( 577.8000000000001 , 2951.8 ) ; System . out . printf ( "%15.12f %15.12f%n" , ll . getLatitude ( ) , ll . getLongitude ( ) ) ; assert Misc . nearlyEquals ( ll . getLongitude ( ) , - 80.21802662821469 , 1.0e-8 ) ; assert Misc . nearlyEquals ( ll . getLatitude ( ) , 26.685132668190793 , 1.0e-8 ) ; }


Input: got to use this or subclass readObservations () [CODESPLIT] public void addObs ( StationObsDatatype sobs ) { if ( null == obsList ) obsList = new ArrayList < StationObsDatatype > ( ) ; obsList . add ( sobs ) ; }


Input:
Look at config and decide if tasks need to be started [CODESPLIT] public void scheduleTasks ( FeatureCollectionConfig config , Logger logger ) { if ( disabled || failed ) return ; if ( logger == null ) logger = fcLogger ; FeatureCollectionConfig . UpdateConfig updateConfig = ( isTdm ) ? config . tdmConfig : config . updateConfig ; if ( updateConfig == null || updateConfig . updateType == CollectionUpdateType . never ) return ; String collectionName = config . getCollectionName ( ) ; // prob dont need to set a job if theres no chron job ? // Job to update the collection org . quartz . JobDataMap map = new org . quartz . JobDataMap ( ) ; map . put ( EVENT_BUS , eventBus ) ; map . put ( COLLECTION_NAME , collectionName ) ; map . put ( LOGGER , logger ) ; JobDetail updateJob = JobBuilder . newJob ( UpdateCollectionJob . class ) . withIdentity ( collectionName , "UpdateCollection" ) . storeDurably ( ) . usingJobData ( map ) . build ( ) ; try { if ( ! scheduler . checkExists ( updateJob . getKey ( ) ) ) { scheduler . addJob ( updateJob , false ) ; } else { logger . warn ( "scheduler failed to add updateJob for " + updateJob . getKey ( ) + ". Another Job exists with that identification." ) ; } } catch ( Throwable e ) { logger . error ( "scheduler failed to add updateJob for " + config , e ) ; return ; } // task to run the job on startup if ( updateConfig . startupType != CollectionUpdateType . never ) { map = new org . quartz . JobDataMap ( ) ; map . put ( UpdateType , updateConfig . startupType ) ; map . put ( Source , "startup" ) ; Date runTime = new Date ( new Date ( ) . getTime ( ) + startupWait ) ; // wait startupWait before trigger SimpleTrigger startupTrigger = ( SimpleTrigger ) TriggerBuilder . newTrigger ( ) . withIdentity ( collectionName , "startup" ) . startAt ( runTime ) . forJob ( updateJob ) . usingJobData ( map ) . build ( ) ; try { scheduler . scheduleJob ( startupTrigger ) ; logger . info ( "scheduleJob startup scan force={} for '{}' at {}" , updateConfig . startupType . toString ( ) , config . collectionName , runTime ) ; } catch ( Throwable e ) { logger . error ( "scheduleJob failed to schedule startup Job for " + config , e ) ; return ; } } // task to run the job periodically, with rescan if ( updateConfig . rescan != null ) { map = new org . quartz . JobDataMap ( ) ; map . put ( UpdateType , updateConfig . updateType ) ; map . put ( Source , "rescan" ) ; CronTrigger rescanTrigger = TriggerBuilder . newTrigger ( ) . withIdentity ( collectionName , "rescan" ) . withSchedule ( CronScheduleBuilder . cronSchedule ( updateConfig . rescan ) ) . forJob ( updateJob ) . usingJobData ( map ) . build ( ) ; try { scheduler . scheduleJob ( rescanTrigger ) ; logger . info ( "scheduleJob recurring scan for '{}' cronExpr={}" , config . collectionName , updateConfig . rescan ) ; } catch ( Throwable e ) { logger . error ( "scheduleJob failed to schedule cron Job" , e ) ; // e.printStackTrace(); } } /* updating the proto dataset
    FeatureCollectionConfig.ProtoConfig pconfig = config.protoConfig;
    if (pconfig.change != null) {
      org.quartz.JobDataMap pmap = new org.quartz.JobDataMap();
      pmap.put(DCM_NAME, manager);
      map.put(LOGGER, logger);
      JobDetail protoJob = JobBuilder.newJob(ChangeProtoJob.class)
              .withIdentity(jobName, "UpdateProto")
              .usingJobData(pmap)
              .storeDurably()
              .build();

      try {
        CronTrigger protoTrigger = TriggerBuilder.newTrigger()
                .withIdentity(jobName, "rereadProto")
                .withSchedule(CronScheduleBuilder.cronSchedule(pconfig.change))
                .build();
        scheduler.scheduleJob(protoJob, protoTrigger);
        if (logger != null)logger.info("Schedule proto update for '{}' cronExpr={}", config.collectionName, pconfig.change);

      } catch (Throwable e) {
        if (logger != null)logger.error("cronExecutor failed to schedule RereadProtoJob", e);
        // e.printStackTrace();
      }
    } */ }


Input: Is want contained in this Range? [CODESPLIT] public boolean contains ( int want ) { if ( want < first ( ) ) return false ; if ( want > last ( ) ) return false ; if ( stride == 1 ) return true ; return ( want - first ) % stride == 0 ; }


Input:
Create a new Range by composing a Range that is reletive to this Range . Revised 2013 / 04 / 19 by Dennis Heimbigner to handle edge cases . See the commentary associated with the netcdf - c file dceconstraints . h function dceslicecompose () . [CODESPLIT] public Range compose ( Range r ) throws InvalidRangeException { if ( ( length ( ) == 0 ) || ( r . length ( ) == 0 ) ) return EMPTY ; if ( this == VLEN || r == VLEN ) return VLEN ; /* if(false) {// Original version
    // Note that this version assumes that range r is
    // correct with respect to this.
    int first = element(r.first());
    int stride = stride() * r.stride();
    int last = element(r.last());
    return new Range(name, first, last, stride);
} else {//new version: handles versions all values of r. */ int sr_stride = this . stride * r . stride ; int sr_first = element ( r . first ( ) ) ; // MAP(this,i) == element(i) int lastx = element ( r . last ( ) ) ; int sr_last = ( last ( ) < lastx ? last ( ) : lastx ) ; //min(last(),lastx) //unused int sr_length = (sr_last + 1) - sr_first; return new Range ( name , sr_first , sr_last , sr_stride ) ; }


Input: Create a new Range by compacting this Range by removing the stride . first = first / stride last = last / stride stride = 1 . [CODESPLIT] public Range compact ( ) throws InvalidRangeException { if ( stride == 1 ) return this ; int first = first ( ) / stride ; // LOOK WTF ? int last = first + length ( ) - 1 ; return new Range ( name , first , last , 1 ) ; }


Input: Get ith element [CODESPLIT] public int element ( int i ) throws InvalidRangeException { if ( i < 0 ) throw new InvalidRangeException ( "i must be >= 0" ) ; if ( i >= length ) throw new InvalidRangeException ( "i must be < length" ) ; return first + i * stride ; }


Input: Get the index for this element : inverse of element [CODESPLIT] public int index ( int want ) throws InvalidRangeException { if ( want < first ) throw new InvalidRangeException ( "elem must be >= first" ) ; int result = ( want - first ) / stride ; if ( result > length ) throw new InvalidRangeException ( "elem must be <= first = n * stride" ) ; return result ; }


Input: Create a new Range by intersecting with a Range using same interval as this Range . NOTE : we dont yet support intersection when both Ranges have strides [CODESPLIT] public Range intersect ( Range r ) throws InvalidRangeException { if ( ( length ( ) == 0 ) || ( r . length ( ) == 0 ) ) return EMPTY ; if ( this == VLEN || r == VLEN ) return VLEN ; int last = Math . min ( this . last ( ) , r . last ( ) ) ; int resultStride = stride * r . stride ( ) ; int useFirst ; if ( resultStride == 1 ) { // both strides are 1 useFirst = Math . max ( this . first ( ) , r . first ( ) ) ; } else if ( stride == 1 ) { // then r has a stride if ( r . first ( ) >= first ( ) ) useFirst = r . first ( ) ; else { int incr = ( first ( ) - r . first ( ) ) / resultStride ; useFirst = r . first ( ) + incr * resultStride ; if ( useFirst < first ( ) ) useFirst += resultStride ; } } else if ( r . stride == 1 ) { // then this has a stride if ( first ( ) >= r . first ( ) ) useFirst = first ( ) ; else { int incr = ( r . first ( ) - first ( ) ) / resultStride ; useFirst = first ( ) + incr * resultStride ; if ( useFirst < r . first ( ) ) useFirst += resultStride ; } } else { throw new UnsupportedOperationException ( "Intersection when both ranges have a stride" ) ; } if ( useFirst > last ) return EMPTY ; return new Range ( name , useFirst , last , resultStride ) ; }


Input: Determine if a given Range intersects this one . NOTE : we dont yet support intersection when both Ranges have strides [CODESPLIT] public boolean intersects ( Range r ) { if ( ( length ( ) == 0 ) || ( r . length ( ) == 0 ) ) return false ; if ( this == VLEN || r == VLEN ) return true ; int last = Math . min ( this . last ( ) , r . last ( ) ) ; int resultStride = stride * r . stride ( ) ; int useFirst ; if ( resultStride == 1 ) { // both strides are 1 useFirst = Math . max ( this . first ( ) , r . first ( ) ) ; } else if ( stride == 1 ) { // then r has a stride if ( r . first ( ) >= first ( ) ) useFirst = r . first ( ) ; else { int incr = ( first ( ) - r . first ( ) ) / resultStride ; useFirst = r . first ( ) + incr * resultStride ; if ( useFirst < first ( ) ) useFirst += resultStride ; } } else if ( r . stride ( ) == 1 ) { // then this has a stride if ( first ( ) >= r . first ( ) ) useFirst = first ( ) ; else { int incr = ( r . first ( ) - first ( ) ) / resultStride ; useFirst = first ( ) + incr * resultStride ; if ( useFirst < r . first ( ) ) useFirst += resultStride ; } } else { throw new UnsupportedOperationException ( "Intersection when both ranges have a stride" ) ; } return ( useFirst <= last ) ; }


Input: Create a new Range shifting this range by a constant factor . [CODESPLIT] public Range shiftOrigin ( int origin ) throws InvalidRangeException { if ( this == VLEN ) return VLEN ; int first = first ( ) - origin ; int last = last ( ) - origin ; return new Range ( name , first , last , stride ) ; }


Input: Create a new Range by making the union with a Range using same interval as this Range . NOTE : no strides [CODESPLIT] public Range union ( Range r ) throws InvalidRangeException { if ( length ( ) == 0 ) return r ; if ( this == VLEN || r == VLEN ) return VLEN ; if ( r . length ( ) == 0 ) return this ; int first = Math . min ( this . first ( ) , r . first ( ) ) ; int last = Math . max ( this . last ( ) , r . last ( ) ) ; return new Range ( name , first , last ) ; }


Input: Find the first element in a strided array after some index start . Return the smallest element k in the Range such that <ul > <li > k > = first <li > k > = start <li > k < = last <li > k = element of this Range < / ul > [CODESPLIT] public int getFirstInInterval ( int start ) { if ( start > last ( ) ) return - 1 ; if ( start <= first ) return first ; if ( stride == 1 ) return start ; int offset = start - first ; int i = offset / stride ; i = ( offset % stride == 0 ) ? i : i + 1 ; // round up return first + i * stride ; }


Input: package private . use Array . factory () [CODESPLIT] static ArrayLong factory ( Index index , boolean isUnsigned ) { return ArrayLong . factory ( index , isUnsigned , null ) ; }


Input: copy from javaArray to storage using the iterator : used by factory ( Object ) ; [CODESPLIT] protected void copyFrom1DJavaArray ( IndexIterator iter , Object javaArray ) { long [ ] ja = ( long [ ] ) javaArray ; for ( long aJa : ja ) iter . setLongNext ( aJa ) ; }


Input: Read data subset from file for a variable create primitive array . [CODESPLIT] protected Object readData ( Layout index , DataType dataType ) throws java . io . IOException { return IospHelper . readDataFill ( raf , index , dataType , null , - 1 ) ; }


Input: Read data subset from file for a variable to WritableByteChannel . Will send as bigendian since thats what the underlying file has . [CODESPLIT] protected long readData ( Layout index , DataType dataType , WritableByteChannel out ) throws java . io . IOException { long count = 0 ; if ( dataType . getPrimitiveClassType ( ) == byte . class || dataType == DataType . CHAR ) { while ( index . hasNext ( ) ) { Layout . Chunk chunk = index . next ( ) ; count += raf . readToByteChannel ( out , chunk . getSrcPos ( ) , chunk . getNelems ( ) ) ; } } else if ( dataType . getPrimitiveClassType ( ) == short . class ) { while ( index . hasNext ( ) ) { Layout . Chunk chunk = index . next ( ) ; count += raf . readToByteChannel ( out , chunk . getSrcPos ( ) , 2 * chunk . getNelems ( ) ) ; } } else if ( dataType . getPrimitiveClassType ( ) == int . class || ( dataType == DataType . FLOAT ) ) { while ( index . hasNext ( ) ) { Layout . Chunk chunk = index . next ( ) ; count += raf . readToByteChannel ( out , chunk . getSrcPos ( ) , 4 * chunk . getNelems ( ) ) ; } } else if ( ( dataType == DataType . DOUBLE ) || dataType . getPrimitiveClassType ( ) == long . class ) { while ( index . hasNext ( ) ) { Layout . Chunk chunk = index . next ( ) ; count += raf . readToByteChannel ( out , chunk . getSrcPos ( ) , 8 * chunk . getNelems ( ) ) ; } } return count ; }


Input: write data to a file for a variable . [CODESPLIT] protected void writeData ( Array values , Layout index , DataType dataType ) throws java . io . IOException { if ( ( dataType == DataType . BYTE ) || ( dataType == DataType . CHAR ) ) { IndexIterator ii = values . getIndexIterator ( ) ; while ( index . hasNext ( ) ) { Layout . Chunk chunk = index . next ( ) ; raf . seek ( chunk . getSrcPos ( ) ) ; for ( int k = 0 ; k < chunk . getNelems ( ) ; k ++ ) raf . write ( ii . getByteNext ( ) ) ; } return ; } else if ( dataType == DataType . STRING ) { // LOOK not legal IndexIterator ii = values . getIndexIterator ( ) ; while ( index . hasNext ( ) ) { Layout . Chunk chunk = index . next ( ) ; raf . seek ( chunk . getSrcPos ( ) ) ; for ( int k = 0 ; k < chunk . getNelems ( ) ; k ++ ) { String val = ( String ) ii . getObjectNext ( ) ; if ( val != null ) raf . write ( val . getBytes ( CDM . utf8Charset ) ) ; // LOOK ?? } } return ; } else if ( dataType == DataType . SHORT ) { IndexIterator ii = values . getIndexIterator ( ) ; while ( index . hasNext ( ) ) { Layout . Chunk chunk = index . next ( ) ; raf . seek ( chunk . getSrcPos ( ) ) ; for ( int k = 0 ; k < chunk . getNelems ( ) ; k ++ ) raf . writeShort ( ii . getShortNext ( ) ) ; } return ; } else if ( dataType == DataType . INT ) { IndexIterator ii = values . getIndexIterator ( ) ; while ( index . hasNext ( ) ) { Layout . Chunk chunk = index . next ( ) ; raf . seek ( chunk . getSrcPos ( ) ) ; for ( int k = 0 ; k < chunk . getNelems ( ) ; k ++ ) raf . writeInt ( ii . getIntNext ( ) ) ; } return ; } else if ( dataType == DataType . FLOAT ) { IndexIterator ii = values . getIndexIterator ( ) ; while ( index . hasNext ( ) ) { Layout . Chunk chunk = index . next ( ) ; raf . seek ( chunk . getSrcPos ( ) ) ; for ( int k = 0 ; k < chunk . getNelems ( ) ; k ++ ) raf . writeFloat ( ii . getFloatNext ( ) ) ; } return ; } else if ( dataType == DataType . DOUBLE ) { IndexIterator ii = values . getIndexIterator ( ) ; while ( index . hasNext ( ) ) { Layout . Chunk chunk = index . next ( ) ; raf . seek ( chunk . getSrcPos ( ) ) ; for ( int k = 0 ; k < chunk . getNelems ( ) ; k ++ ) raf . writeDouble ( ii . getDoubleNext ( ) ) ; } return ; } throw new IllegalStateException ( "dataType= " + dataType ) ; }


Input: / * <! -- C : / data / dt2 / station / madis2 . sao -- > <stationCollection > <table dim = maxStaticIds limit = nStaticIds > <lastLink > lastRecord< / lastLink > [CODESPLIT] public TableConfig getConfig ( FeatureType wantFeatureType , NetcdfDataset ds , Formatter errlog ) { Dimension obsDim = Evaluator . getDimension ( ds , "recNum" , errlog ) ; if ( obsDim == null ) { errlog . format ( "MADIS: must have an Observation dimension: named recNum" ) ; return null ; } VNames vn = getVariableNames ( ds , errlog ) ; String levVarName = null ; String levDimName = null ; boolean hasStruct = Evaluator . hasNetcdf3RecordStructure ( ds ) ; FeatureType ft = Evaluator . getFeatureType ( ds , ":thredds_data_type" , errlog ) ; if ( null == ft ) { if ( ( ds . findDimension ( "manLevel" ) != null ) && ( ds . findVariable ( "prMan" ) != null ) ) { ft = FeatureType . STATION_PROFILE ; levVarName = "prMan" ; levDimName = "manLevel" ; } else if ( ( ds . findDimension ( "level" ) != null ) && ( ds . findVariable ( "levels" ) != null ) ) { ft = FeatureType . STATION_PROFILE ; levVarName = "levels" ; levDimName = "level" ; } } if ( null == ft ) ft = FeatureType . POINT ; // points if ( ( wantFeatureType == FeatureType . POINT ) || ( ft == FeatureType . POINT ) ) { TableConfig ptTable = new TableConfig ( Table . Type . Structure , hasStruct ? "record" : obsDim . getShortName ( ) ) ; ptTable . structName = "record" ; ptTable . featureType = FeatureType . POINT ; ptTable . structureType = hasStruct ? TableConfig . StructureType . Structure : TableConfig . StructureType . PsuedoStructure ; ptTable . dimName = obsDim . getShortName ( ) ; ptTable . time = vn . obsTime ; ptTable . timeNominal = vn . nominalTime ; ptTable . lat = vn . lat ; ptTable . lon = vn . lon ; ptTable . elev = vn . elev ; return ptTable ; } if ( ft == FeatureType . STATION ) { TableConfig stnTable = new TableConfig ( Table . Type . Construct , "station" ) ; stnTable . featureType = FeatureType . STATION ; TableConfig obs = new TableConfig ( Table . Type . ParentId , "record" ) ; obs . parentIndex = vn . stnId ; obs . dimName = Evaluator . getDimensionName ( ds , "recNum" , errlog ) ; obs . time = vn . obsTime ; obs . timeNominal = vn . nominalTime ; obs . stnId = vn . stnId ; obs . stnDesc = vn . stnDesc ; obs . lat = vn . lat ; obs . lon = vn . lon ; obs . elev = vn . elev ; stnTable . addChild ( obs ) ; return stnTable ; } else if ( ft == FeatureType . STATION_PROFILE ) { TableConfig stnTable = new TableConfig ( Table . Type . Construct , "station" ) ; stnTable . featureType = FeatureType . STATION_PROFILE ; TableConfig obs = new TableConfig ( Table . Type . ParentId , "record" ) ; obs . parentIndex = vn . stnId ; obs . dimName = Evaluator . getDimensionName ( ds , "recNum" , errlog ) ; obs . time = vn . obsTime ; obs . timeNominal = vn . nominalTime ; obs . stnId = vn . stnId ; obs . stnDesc = vn . stnDesc ; obs . lat = vn . lat ; obs . lon = vn . lon ; obs . stnAlt = vn . elev ; stnTable . addChild ( obs ) ; TableConfig lev = new TableConfig ( Table . Type . MultidimInner , "mandatory" ) ; lev . elev = levVarName ; lev . outerName = obs . dimName ; lev . innerName = levDimName ; obs . addChild ( lev ) ; return stnTable ; } return null ; }


Input: Read the data values ( parameters are ignored ) . Use the start stop and stride values that were set by the constraint evaluator . [CODESPLIT] public boolean read ( String datasetName , Object specialO ) throws IOException { boolean hasStride = false ; Array a ; try { if ( debugRead ) { System . out . println ( "NcSDCharArray read " + ncVar . getFullName ( ) ) ; for ( int i = 0 ; i < numDimensions ( ) ; i ++ ) { DArrayDimension d = getDimension ( i ) ; System . out . println ( " " + d . getEncodedName ( ) + " " + getStart ( i ) + " " + getStop ( i ) + " " + getStride ( i ) ) ; } } // set up the netcdf read int n = numDimensions ( ) ; int [ ] origin = new int [ n + 1 ] ; int [ ] shape = new int [ n + 1 ] ; for ( int i = 0 ; i < n ; i ++ ) { origin [ i ] = getStart ( i ) ; shape [ i ] = getStop ( i ) - getStart ( i ) + 1 ; hasStride = hasStride || ( getStride ( i ) > 1 ) ; } origin [ n ] = 0 ; shape [ n ] = strLen ; a = ncVar . read ( origin , shape ) ; if ( debugRead ) System . out . println ( "  Read = " + a . getSize ( ) + " elems of type = " + a . getElementType ( ) ) ; // deal with strides using a section if ( hasStride ) { List < Range > ranges = new ArrayList <> ( ) ; for ( int i = 0 ; i < n ; i ++ ) { int s = getStride ( i ) ; if ( s > 1 ) { // otherwise null, means "take all elements" ranges . add ( new Range ( 0 , shape [ i ] , s ) ) ; if ( debugRead ) System . out . println ( " Section dim " + i + " stride = " + s ) ; } } ranges . add ( null ) ; //  get all a = a . section ( ranges ) ; if ( debugRead ) System . out . println ( "   section size " + a . getSize ( ) ) ; } } catch ( InvalidDimensionException e ) { log . error ( "read char array" , e ) ; throw new IllegalStateException ( "NcSDCharArray InvalidDimensionException" ) ; } catch ( InvalidRangeException e ) { log . error ( "read char array" , e ) ; throw new IllegalStateException ( "NcSDCharArray InvalidRangeException" ) ; } setData ( a ) ; return ( false ) ; }


Input: Writes data to a <code > DataOutputStream< / code > . This method is used on the server side of the OPeNDAP client / server connection and possibly by GUI clients which need to download OPeNDAP data manipulate it and then resave it as a binary file . [CODESPLIT] public void externalize ( DataOutputStream sink ) throws IOException { for ( int i = 0 ; i < vals . length ; i ++ ) { sink . writeBoolean ( vals [ i ] ) ; } }


Input: Write a subset of the data to a <code > DataOutputStream< / code > . [CODESPLIT] public void externalize ( DataOutputStream sink , int start , int stop , int stride ) throws IOException { for ( int i = start ; i <= stop ; i += stride ) sink . writeBoolean ( vals [ i ] ) ; }


Input: Create a new primitive vector using a subset of the data . [CODESPLIT] public PrimitiveVector subset ( int start , int stop , int stride ) { BooleanPrimitiveVector n = new BooleanPrimitiveVector ( getTemplate ( ) ) ; stride = Math . max ( stride , 1 ) ; stop = Math . max ( start , stop ) ; int length = 1 + ( stop - start ) / stride ; n . setLength ( length ) ; int count = 0 ; for ( int i = start ; i <= stop ; i += stride ) { n . setValue ( count , vals [ i ] ) ; count ++ ; } return n ; }


Input: Returns a clone of this <code > BooleanPrimitiveVector< / code > . See DAPNode . cloneDag () [CODESPLIT] public DAPNode cloneDAG ( CloneMap map ) throws CloneNotSupportedException { BooleanPrimitiveVector v = ( BooleanPrimitiveVector ) super . cloneDAG ( map ) ; if ( vals != null ) { v . vals = new boolean [ vals . length ] ; System . arraycopy ( vals , 0 , v . vals , 0 , vals . length ) ; } return v ; }


Input: / * type info codes from hntdefs . h #define DFNT_UCHAR8 3 #define DFNT_CHAR8 4 #define DFNT_FLOAT32 5 #define DFNT_FLOAT64 6 [CODESPLIT] static DataType setDataType ( short type , Variable v ) { DataType dt ; switch ( type ) { case 3 : dt = DataType . UBYTE ; break ; case 4 : dt = DataType . CHAR ; break ; case 5 : dt = DataType . FLOAT ; break ; case 6 : dt = DataType . DOUBLE ; break ; case 20 : dt = DataType . BYTE ; break ; case 21 : dt = DataType . UBYTE ; break ; case 22 : dt = DataType . SHORT ; break ; case 23 : dt = DataType . USHORT ; break ; case 24 : dt = DataType . INT ; break ; case 25 : dt = DataType . UINT ; break ; case 26 : dt = DataType . LONG ; break ; case 27 : dt = DataType . ULONG ; break ; default : throw new IllegalStateException ( "unknown type= " + type ) ; } if ( v != null ) { v . setDataType ( dt ) ; } return dt ; }


Input: return sorted catalogs [CODESPLIT] public Iterable < ? extends CatalogExt > getCatalogs ( ) { if ( catalogs == null ) readCatalogs ( ) ; List < CatalogExt > result = new ArrayList <> ( ) ; for ( CatalogExt ext : catalogs . values ( ) ) result . ( ext ) ; Collections . sort ( result , ( o1 , o2 ) -> o1 . getCatRelLocation ( ) . compareTo ( o2 . getCatRelLocation ( ) ) ) ; // java 8 lambda, baby return result ; }


Input: Accessors [CODESPLIT] @ Override public void addEntry ( String urlpath , String fileprefix ) throws DapException { // Canonicalize the urlpath String urlprefix = DapUtil . canonicalpath ( urlpath ) ; // Canonicalize the file path fileprefix = DapUtil . canonicalpath ( fileprefix ) ; url2path . put ( urlprefix , fileprefix ) ; // overwrite path2url . put ( fileprefix , urlprefix ) ; // overwrite }


Input: File loader [CODESPLIT] public void load ( String filepath ) throws IOException { String [ ] lines ; try ( InputStream is = new FileInputStream ( filepath ) ; ) { String content = DapUtil . readtextfile ( is ) ; lines = content . split ( "[\n]" ) ; } for ( String line : lines ) { String [ ] pieces = line . split ( "[=]" ) ; if ( pieces . length != 2 ) throw new IOException ( "File: " + filepath + "; malformed line: " + line ) ; addEntry ( pieces [ 0 ] , pieces [ 1 ] ) ; } }


Input: URLMap API [CODESPLIT] @ Override public Result mapURL ( String urlpath ) throws DapException { // Canonicalize the urlpath urlpath = DapUtil . canonicalpath ( urlpath ) ; Result result = longestmatch ( url2path , urlpath ) ; return result ; }


Input: delete old databases [CODESPLIT] public static void cleanupBefore ( String pathname , long trackerNumber ) { for ( long tnum = trackerNumber - 1 ; tnum > 0 ; tnum -- ) { File oldDatabaseFile = new File ( pathname + datasetName + "." + tnum ) ; if ( ! oldDatabaseFile . exists ( ) ) break ; if ( oldDatabaseFile . delete ( ) ) { catalogInitLog . info ( "DatasetTrackerChronicle deleted {} " , oldDatabaseFile . getAbsolutePath ( ) ) ; } else { catalogInitLog . error ( "DatasetTrackerChronicle not able to delete {} " , oldDatabaseFile . getAbsolutePath ( ) ) ; } } }


Input: Set the grid nav block values [CODESPLIT] public void setValues ( float [ ] values ) { vals = values ; proj = GempakUtil . ST_ITOC ( Float . floatToIntBits ( vals [ 1 ] ) ) . trim ( ) ; addParam ( PROJ , proj ) ; addParam ( GDS_KEY , this . toString ( ) ) ; setParams ( ) ; }


Input: Set the parameters for the GDS . TODO Add the following : The following simple map projections may be specified : [CODESPLIT] private void setParams ( ) { String angle1 = String . valueOf ( vals [ 10 ] ) ; String angle2 = String . valueOf ( vals [ 11 ] ) ; String angle3 = String . valueOf ( vals [ 12 ] ) ; String lllat = String . valueOf ( vals [ 6 ] ) ; String lllon = String . valueOf ( vals [ 7 ] ) ; String urlat = String . valueOf ( vals [ 8 ] ) ; String urlon = String . valueOf ( vals [ 9 ] ) ; addParam ( NX , String . valueOf ( vals [ 4 ] ) ) ; addParam ( NY , String . valueOf ( vals [ 5 ] ) ) ; addParam ( LA1 , lllat ) ; addParam ( LO1 , lllon ) ; addParam ( LA2 , urlat ) ; addParam ( LO2 , urlon ) ; switch ( proj ) { case "STR" : case "NPS" : case "SPS" : addParam ( LOV , angle2 ) ; // TODO:  better to just set pole? if ( proj . equals ( "SPS" ) ) { addParam ( "NpProj" , "false" ) ; } break ; case "LCC" : case "SCC" : addParam ( LATIN1 , angle1 ) ; addParam ( LOV , angle2 ) ; addParam ( LATIN2 , angle3 ) ; // TODO: test this break ; case "MER" : case "MCD" : String standardLat ; if ( vals [ 10 ] == 0 ) { // use average latitude float lat = ( vals [ 8 ] + vals [ 6 ] ) / 2 ; standardLat = String . valueOf ( lat ) ; } else { standardLat = angle1 ; } addParam ( "Latin" , standardLat ) ; addParam ( LOV , angle2 ) ; break ; case "CED" : double lllatv = vals [ 6 ] ; double lllonv = vals [ 7 ] ; double urlatv = vals [ 8 ] ; double urlonv = vals [ 9 ] ; if ( urlonv <= lllonv ) { urlonv += 360. ; } double dx = Math . abs ( ( urlonv - lllonv ) / ( vals [ 4 ] - 1 ) ) ; double dy = Math . abs ( ( urlatv - lllatv ) / ( vals [ 5 ] - 1 ) ) ; addParam ( DX , String . valueOf ( dx ) ) ; addParam ( DY , String . valueOf ( dy ) ) ; addParam ( LO2 , String . valueOf ( urlonv ) ) ; break ; } }


Input: seems to handle swath as well ?? [CODESPLIT] public void writeGrid ( String gridDataset_filename , String gridName , int time , int level , boolean greyScale , LatLonRect pt ) throws IOException { try ( GridDataset dataset = ucar . nc2 . dt . grid . GridDataset . open ( gridDataset_filename ) ) { GridDatatype grid = dataset . findGridDatatype ( gridName ) ; if ( grid == null ) { throw new IllegalArgumentException ( "No grid named " + gridName + " in fileName" ) ; } GridCoordSystem gcs = grid . getCoordinateSystem ( ) ; ProjectionImpl proj = grid . getProjection ( ) ; if ( ! gcs . isRegularSpatial ( ) ) { Attribute att = dataset . findGlobalAttributeIgnoreCase ( "datasetId" ) ; if ( att != null && att . getStringValue ( ) . contains ( "DMSP" ) ) { // LOOK!! writeSwathGrid ( gridDataset_filename , gridName , time , level , greyScale , pt ) ; return ; } else { throw new IllegalArgumentException ( "Must have 1D x and y axes for " + grid . getFullName ( ) ) ; } } CoordinateAxis1D xaxis = ( CoordinateAxis1D ) gcs . getXHorizAxis ( ) ; CoordinateAxis1D yaxis = ( CoordinateAxis1D ) gcs . getYHorizAxis ( ) ; if ( ! xaxis . isRegular ( ) || ! yaxis . isRegular ( ) ) { throw new IllegalArgumentException ( "Must be evenly spaced grid = " + grid . getFullName ( ) ) ; } // read in data Array data = grid . readDataSlice ( time , level , - 1 , - 1 ) ; Array lon = xaxis . read ( ) ; Array lat = yaxis . read ( ) ; // units may need to be scaled to meters double scaler = ( xaxis . getUnitsString ( ) . equalsIgnoreCase ( "km" ) ) ? 1000.0 : 1.0 ; if ( yaxis . getCoordValue ( 0 ) < yaxis . getCoordValue ( 1 ) ) { data = data . flip ( 0 ) ; lat = lat . flip ( 0 ) ; } if ( gcs . isLatLon ( ) ) { data = geoShiftDataAtLon ( data , lon ) ; lon = geoShiftLon ( lon ) ; } // now it is time to subset the data out of latlonrect // it is assumed that latlonrect pt is in +-180 LatLonPointImpl llp0 = pt . getLowerLeftPoint ( ) ; LatLonPointImpl llpn = pt . getUpperRightPoint ( ) ; double minLon = llp0 . getLongitude ( ) ; double minLat = llp0 . getLatitude ( ) ; double maxLon = llpn . getLongitude ( ) ; double maxLat = llpn . getLatitude ( ) ; // (x1, y1) is upper left point and (x2, y2) is lower right point int x1 ; int x2 ; int y1 ; int y2 ; double xStart ; double yStart ; if ( ! gcs . isLatLon ( ) ) { ProjectionPoint pjp0 = proj . latLonToProj ( maxLat , minLon ) ; x1 = getXIndex ( lon , pjp0 . getX ( ) , 0 ) ; y1 = getYIndex ( lat , pjp0 . getY ( ) , 0 ) ; yStart = pjp0 . getY ( ) * 1000.0 ; //latArray[y1]; xStart = pjp0 . getX ( ) * 1000.0 ; //lonArray[x1]; ProjectionPoint pjpn = proj . latLonToProj ( minLat , maxLon ) ; x2 = getXIndex ( lon , pjpn . getX ( ) , 1 ) ; y2 = getYIndex ( lat , pjpn . getY ( ) , 1 ) ; } else { xStart = minLon ; yStart = maxLat ; x1 = getLonIndex ( lon , minLon , 0 ) ; y1 = getLatIndex ( lat , maxLat , 0 ) ; x2 = getLonIndex ( lon , maxLon , 1 ) ; y2 = getLatIndex ( lat , minLat , 1 ) ; } // data must go from top to bottom double xInc = xaxis . getIncrement ( ) * scaler ; double yInc = Math . abs ( yaxis . getIncrement ( ) ) * scaler ; // subsetting data inside the box Array data1 = getYXDataInBox ( data , x1 , x2 , y1 , y2 ) ; if ( pageNumber > 1 ) { geotiff . initTags ( ) ; } // write it out writeGrid ( grid , data1 , greyScale , xStart , yStart , xInc , yInc , pageNumber ) ; pageNumber ++ ; } }


Input: Write Swath Grid data to the geotiff file . [CODESPLIT] private void writeSwathGrid ( String fileName , String gridName , int time , int level , boolean greyScale , LatLonRect llr ) throws IOException { GridDataset dataset = ucar . nc2 . dt . grid . GridDataset . open ( fileName ) ; GridDatatype grid = dataset . findGridDatatype ( gridName ) ; GridCoordSystem gcs = grid . getCoordinateSystem ( ) ; ProjectionImpl proj = grid . getProjection ( ) ; CoordinateAxis2D xaxis = ( CoordinateAxis2D ) gcs . getXHorizAxis ( ) ; CoordinateAxis2D yaxis = ( CoordinateAxis2D ) gcs . getYHorizAxis ( ) ; // read in data Array data = grid . readDataSlice ( time , level , - 1 , - 1 ) ; Array lon = xaxis . read ( ) ; Array lat = yaxis . read ( ) ; double [ ] swathInfo = getSwathLatLonInformation ( lat , lon ) ; // units may need to be scaled to meters double scaler = ( xaxis . getUnitsString ( ) . equalsIgnoreCase ( "km" ) ) ? 1000.0 : 1.0 ; //if (yaxis.getCoordValue(0, 0) < yaxis.getCoordValue(0, 1)) {//??? data = data . flip ( 0 ) ; //lat = lat.flip(0); //} if ( gcs . isLatLon ( ) ) { data = geoShiftDataAtLon ( data , lon ) ; lon = geoShiftLon ( lon ) ; } double minLon ; double minLat ; double maxLon ; double maxLat ; double xStart ; double yStart ; //upper right point double xInc = swathInfo [ 0 ] * scaler ; double yInc = swathInfo [ 1 ] * scaler ; // (x1, y1) is upper left point and (x2, y2) is lower right point int x1 ; int x2 ; int y1 ; int y2 ; if ( llr == null ) { //get the whole area minLon = swathInfo [ 4 ] ; minLat = swathInfo [ 2 ] ; maxLon = swathInfo [ 5 ] ; maxLat = swathInfo [ 3 ] ; xStart = minLon ; yStart = maxLat ; x1 = 0 ; y1 = 0 ; x2 = ( int ) ( ( maxLon - minLon ) / xInc + 0.5 ) ; y2 = ( int ) ( ( maxLat - minLat ) / yInc + 0.5 ) ; } else { //assign the special area  surrounded by the llr LatLonPointImpl llp0 = llr . getLowerLeftPoint ( ) ; LatLonPointImpl llpn = llr . getUpperRightPoint ( ) ; minLon = ( llp0 . getLongitude ( ) < swathInfo [ 4 ] ) ? swathInfo [ 4 ] : llp0 . getLongitude ( ) ; minLat = ( llp0 . getLatitude ( ) < swathInfo [ 2 ] ) ? swathInfo [ 2 ] : llp0 . getLatitude ( ) ; maxLon = ( llpn . getLongitude ( ) > swathInfo [ 5 ] ) ? swathInfo [ 5 ] : llpn . getLongitude ( ) ; maxLat = ( llpn . getLatitude ( ) > swathInfo [ 3 ] ) ? swathInfo [ 3 ] : llpn . getLatitude ( ) ; //construct the swath  LatLonRect LatLonPointImpl pUpLeft = new LatLonPointImpl ( swathInfo [ 3 ] , swathInfo [ 4 ] ) ; LatLonPointImpl pDownRight = new LatLonPointImpl ( swathInfo [ 2 ] , swathInfo [ 5 ] ) ; LatLonRect swathLLR = new LatLonRect ( pUpLeft , pDownRight ) ; LatLonRect bIntersect = swathLLR . intersect ( llr ) ; if ( bIntersect == null ) { throw new IllegalArgumentException ( "The assigned extent of latitude and longitude is unvalid. No intersection with the swath extent" ) ; } xStart = minLon ; yStart = maxLat ; x1 = ( int ) ( ( minLon - swathInfo [ 4 ] ) / xInc + 0.5 ) ; y1 = ( int ) Math . abs ( ( maxLat - swathInfo [ 3 ] ) / yInc + 0.5 ) ; x2 = ( int ) ( ( maxLon - swathInfo [ 4 ] ) / xInc + 0.5 ) ; y2 = ( int ) Math . abs ( ( minLat - swathInfo [ 3 ] ) / yInc + 0.5 ) ; } if ( ! gcs . isLatLon ( ) ) { ProjectionPoint pjp0 = proj . latLonToProj ( maxLat , minLon ) ; x1 = getXIndex ( lon , pjp0 . getX ( ) , 0 ) ; y1 = getYIndex ( lat , pjp0 . getY ( ) , 0 ) ; yStart = pjp0 . getY ( ) * scaler ; //latArray[y1]; xStart = pjp0 . getX ( ) * scaler ; //lonArray[x1]; ProjectionPoint pjpn = proj . latLonToProj ( minLat , maxLon ) ; x2 = getXIndex ( lon , pjpn . getX ( ) , 1 ) ; y2 = getYIndex ( lat , pjpn . getY ( ) , 1 ) ; } else { //calculate the x1, x2, y1, y2, xstart, ystart. } Array targetImage = getTargetImagerFromSwath ( lat , lon , data , swathInfo ) ; Array interpolatedImage = interpolation ( targetImage ) ; Array clippedImage = getClippedImageFromInterpolation ( interpolatedImage , x1 , x2 , y1 , y2 ) ; //Array clippedImage = getYXDataInBox(interpolatedImage, x1, x2, y1, y2); if ( pageNumber > 1 ) { geotiff . initTags ( ) ; } writeGrid ( grid , clippedImage , greyScale , xStart , yStart , xInc , yInc , pageNumber ) ; pageNumber ++ ; }


Input: interpolate the swath data to regular grid [CODESPLIT] private Array interpolation ( Array arr ) { int [ ] orishape = arr . getShape ( ) ; int width = orishape [ 1 ] ; int height = orishape [ 0 ] ; int pixelNum = width * height ; Array interpolatedArray = Array . factory ( DataType . FLOAT , orishape ) ; for ( int i = 0 ; i < height ; i ++ ) { for ( int j = 0 ; j < width ; j ++ ) { int curIndex = i * width + j ; float curValue = arr . getFloat ( curIndex ) ; if ( curValue == 0 ) //Black hole. Need to fill. { float tempPixelSum = 0 ; int numNeighborHasValue = 0 ; //Get the values of eight neighborhood if ( ( curIndex - 1 >= 0 ) && ( curIndex - 1 < pixelNum ) ) { float left = arr . getFloat ( curIndex - 1 ) ; if ( left > 0 ) { tempPixelSum += left ; numNeighborHasValue ++ ; } } if ( ( curIndex + 1 >= 0 ) && ( curIndex + 1 < pixelNum ) ) { float right = arr . getFloat ( curIndex + 1 ) ; if ( right > 0 ) { tempPixelSum += right ; numNeighborHasValue ++ ; } } if ( ( curIndex - width >= 0 ) && ( curIndex - width < pixelNum ) ) { float up = arr . getFloat ( curIndex - width ) ; if ( up > 0 ) { tempPixelSum += up ; numNeighborHasValue ++ ; } } if ( ( curIndex + width >= 0 ) && ( curIndex + width < pixelNum ) ) { float down = arr . getFloat ( curIndex + width ) ; if ( down > 0 ) { tempPixelSum += down ; numNeighborHasValue ++ ; } } if ( ( curIndex - width - 1 >= 0 ) && ( curIndex - width - 1 < pixelNum ) ) { float upleft = arr . getFloat ( curIndex - width - 1 ) ; if ( upleft > 0 ) { tempPixelSum += upleft ; numNeighborHasValue ++ ; } } if ( ( curIndex - width + 1 >= 0 ) && ( curIndex - width + 1 < pixelNum ) ) { float upright = arr . getFloat ( curIndex - width + 1 ) ; if ( upright > 0 ) { tempPixelSum += upright ; numNeighborHasValue ++ ; } } if ( ( curIndex + width - 1 >= 0 ) && ( curIndex + width - 1 < pixelNum ) ) { float downleft = arr . getFloat ( curIndex + width - 1 ) ; if ( downleft > 0 ) { tempPixelSum += downleft ; numNeighborHasValue ++ ; } } if ( ( curIndex + width + 1 >= 0 ) && ( curIndex + width + 1 < pixelNum ) ) { float downright = arr . getFloat ( curIndex + width + 1 ) ; if ( downright > 0 ) { tempPixelSum += downright ; numNeighborHasValue ++ ; } } if ( tempPixelSum > 0 ) { float val = numNeighborHasValue == 0 ? 0 : tempPixelSum / numNeighborHasValue ; interpolatedArray . setFloat ( curIndex , val ) ; } } else { interpolatedArray . setFloat ( curIndex , curValue ) ; } } } return interpolatedArray ; }


Input: get lat lon information from the swath [CODESPLIT] private double [ ] getSwathLatLonInformation ( Array lat , Array lon ) { // Calculate the increment of latitude and longitude of original swath data // Calculate the size of the boundingBox // element0: Longitude increment // element1: Latitude increment // element2: minLat // element3: maxLat // element4: minLon // element5: maxLon // element6: width of the boundingBox // element7: height of the boundingBox double increment [ ] = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ; IndexIterator latIter = lat . getIndexIterator ( ) ; IndexIterator lonIter = lon . getIndexIterator ( ) ; int numScan = ( lat . getShape ( ) ) [ 0 ] ; int numSample = ( lat . getShape ( ) ) [ 1 ] ; double maxLat = - 91 , minLat = 91 , maxLon = - 181 , minLon = 181 ; float firstLineStartLat = 0 ; float firstLineStartLon = 0 ; float firstLineEndLat = 0 ; float firstLineEndLon = 0 ; float lastLineStartLat = 0 ; float lastLineStartLon = 0 ; float lastLineEndLat = 0 ; float lastLineEndLon = 0 ; for ( int i = 0 ; i < numScan ; i ++ ) { for ( int j = 0 ; j < numSample ; j ++ ) { if ( latIter . hasNext ( ) && lonIter . hasNext ( ) ) { float curLat = latIter . getFloatNext ( ) ; float curLon = lonIter . getFloatNext ( ) ; if ( ( i == 0 ) && ( j == 0 ) ) { firstLineStartLat = curLat ; firstLineStartLon = curLon ; } else if ( ( i == 0 ) && ( j == numSample - 1 ) ) { firstLineEndLat = curLat ; firstLineEndLon = curLon ; } else if ( ( i == numScan - 1 ) && ( j == 0 ) ) { lastLineStartLat = curLat ; lastLineStartLon = curLon ; } else if ( ( i == numScan - 1 ) && ( j == numSample - 1 ) ) { lastLineEndLat = curLat ; lastLineEndLon = curLon ; } } } } double [ ] edgeLat = { firstLineStartLat , firstLineEndLat , lastLineStartLat , lastLineEndLat } ; double [ ] edgeLon = { firstLineStartLon , firstLineEndLon , lastLineStartLon , lastLineEndLon } ; for ( int i = 0 ; i < edgeLat . length ; i ++ ) { maxLat = ( ( maxLat > edgeLat [ i ] ) ? maxLat : edgeLat [ i ] ) ; minLat = ( ( minLat < edgeLat [ i ] ) ? minLat : edgeLat [ i ] ) ; maxLon = ( ( maxLon > edgeLon [ i ] ) ? maxLon : edgeLon [ i ] ) ; minLon = ( ( minLon < edgeLon [ i ] ) ? minLon : edgeLon [ i ] ) ; } double xInc1 = Math . abs ( ( firstLineEndLon - firstLineStartLon ) / numSample ) ; //double xInc2 = Math.abs((lastLineEndLon - lastLineStartLon)/numSample); double yInc1 = Math . abs ( ( lastLineStartLat - firstLineStartLat ) / numScan ) ; //double yInc2 = Math.abs((lastLineEndLat - firstLineEndLat)/numScan); increment [ 0 ] = xInc1 ; // > xInc2 ? xInc1 : xInc2; increment [ 1 ] = yInc1 ; // > yInc2 ? yInc1 : yInc2; increment [ 2 ] = minLat ; increment [ 3 ] = maxLat ; increment [ 4 ] = minLon ; increment [ 5 ] = maxLon ; increment [ 6 ] = ( maxLon - minLon ) / xInc1 ; increment [ 7 ] = ( maxLat - minLat ) / yInc1 ; return increment ; }


Input:
used by H5tiledLayout [CODESPLIT] LayoutTiled . DataChunkIterator getDataChunkIteratorNoFilter ( Section want , int nChunkDim ) throws IOException { /*
    if (if (debugChunkOrder) ) {
    DataChunkIteratorNoFilter iter = new DataChunkIteratorNoFilter(null, nChunkDim);
    int count = 0;
    int last = -1;
    while (iter.hasNext()) {
      LayoutTiled.DataChunk chunk = iter.next();
      System.out.printf("%d : %d%n", count++, tiling.order(chunk.offset));
      if (tiling.order(chunk.offset) <= last)
        System.out.println("HEY");
      last = tiling.order(chunk.offset);
    }
    }*/ return new DataChunkIteratorNoFilter ( want , nChunkDim ) ; }


Input: Convert a LatLonPoint to projection coordinates [CODESPLIT] public ProjectionPoint latLonToProj ( LatLonPoint latLon , ProjectionPointImpl result ) { double toX , toY ; double fromLat = latLon . getLatitude ( ) ; double fromLon = latLon . getLongitude ( ) ; double [ ] [ ] xy = anav . toLinEle ( new double [ ] [ ] { { fromLat } , { fromLon } } ) ; if ( xy == null ) return null ; toX = xy [ 0 ] [ 0 ] ; toY = xy [ 1 ] [ 0 ] ; result . setLocation ( toX , toY ) ; return result ; }


Input: Convert projection coordinates to a LatLonPoint Note : a new object is not created on each call for the return value . [CODESPLIT] public LatLonPoint projToLatLon ( ProjectionPoint world , LatLonPointImpl result ) { double toLat , toLon ; double fromX = world . getX ( ) ; double fromY = world . getY ( ) ; double [ ] [ ] latlon = anav . toLatLon ( new double [ ] [ ] { { fromX } , { fromY } } ) ; toLat = latlon [ 0 ] [ 0 ] ; toLon = latlon [ 1 ] [ 0 ] ; result . setLatitude ( toLat ) ; result . setLongitude ( toLon ) ; return result ; }


Input: Convert lat / lon coordinates to projection coordinates . [CODESPLIT] public float [ ] [ ] latLonToProj ( float [ ] [ ] from , float [ ] [ ] to , int latIndex , int lonIndex ) { float [ ] fromLatA = from [ latIndex ] ; float [ ] fromLonA = from [ lonIndex ] ; float [ ] [ ] xy = anav . toLinEle ( new float [ ] [ ] { fromLatA , fromLonA } ) ; if ( xy == null ) return null ; to [ INDEX_X ] = xy [ 0 ] ; to [ INDEX_Y ] = xy [ 1 ] ; return to ; }


Input: Convert lat / lon coordinates to projection coordinates . [CODESPLIT] public float [ ] [ ] projToLatLon ( float [ ] [ ] from , float [ ] [ ] to ) { float [ ] fromXA = from [ INDEX_X ] ; float [ ] fromYA = from [ INDEX_Y ] ; float [ ] [ ] latlon = anav . toLatLon ( new float [ ] [ ] { fromXA , fromYA } ) ; to [ INDEX_LAT ] = latlon [ 0 ] ; to [ INDEX_LON ] = latlon [ 1 ] ; return to ; }


Input:
This returns true when the line between pt1 and pt2 crosses the seam . When the cone is flattened the seam is lon0 + - 180 . [CODESPLIT] public boolean crossSeam ( ProjectionPoint pt1 , ProjectionPoint pt2 ) { // either point is infinite
 if ( ProjectionPointImpl . isInfinite ( pt1 ) || ProjectionPointImpl . isInfinite ( pt2 ) ) { return true ; } if ( Double . isNaN ( pt1 . getX ( ) ) || Double . isNaN ( pt1 . getY ( ) ) || Double . isNaN ( pt2 . getX ( ) ) || Double . isNaN ( pt2 . getY ( ) ) ) { return true ; } // opposite signed X values, larger then 5000 km
 return ( pt1 . getX ( ) * pt2 . getX ( ) < 0 ) && ( Math . abs ( pt1 . getX ( ) - pt2 . getX ( ) ) > 5000.0 ) ; }


Input: make a double array out of an int array [CODESPLIT] private double [ ] makeDoubleArray ( int [ ] ints ) { double [ ] newArray = new double [ ints . length ] ; for ( int i = 0 ; i < ints . length ; i ++ ) { newArray [ i ] = ints [ i ] ; } return newArray ; }


Input: ///////////////////////////////////////////////////////// [CODESPLIT] @ RequestMapping ( value = { "**/dataset.xml" , "**/pointDataset.xml" } ) // Same response for both Grid and GridAsPoint. public ModelAndView getDatasetDescriptionXml ( HttpServletRequest req , HttpServletResponse res ) throws IOException { String datasetPath = getDatasetPath ( req ) ; try ( CoverageCollection gcd = TdsRequestedDataset . getCoverageCollection ( req , res , datasetPath ) ) { if ( gcd == null ) return null ; // restricted dataset String datasetUrlPath = buildDatasetUrl ( datasetPath ) ; CoverageDatasetCapabilities writer = new CoverageDatasetCapabilities ( gcd , "path" ) ; Document doc = writer . makeDatasetDescription ( ) ; Element root = doc . getRootElement ( ) ; root . setAttribute ( "location" , datasetUrlPath ) ; root . addContent ( makeAcceptXML ( SupportedOperation . GRID_REQUEST ) ) ; return new ModelAndView ( "threddsXmlView" , "Document" , doc ) ; } }


Input: Supported for backwards compatibility . We prefer that datasetBoundaries . wkt or datasetBoundaries . json are used . [CODESPLIT] @ RequestMapping ( "**/datasetBoundaries.xml" ) public void getDatasetBoundaries ( NcssParamsBean params , HttpServletRequest req , HttpServletResponse res ) throws IOException , UnsupportedResponseFormatException { SupportedFormat format = SupportedOperation . DATASET_BOUNDARIES_REQUEST . getSupportedFormat ( params . getAccept ( ) ) ; switch ( format ) { case WKT : getDatasetBoundariesWKT ( req , res ) ; break ; case JSON : getDatasetBoundariesGeoJSON ( req , res ) ; break ; default : throw new IllegalArgumentException ( String . format ( "Expected %s or %s, but got %s" , SupportedFormat . WKT , SupportedFormat . JSON , format ) ) ; } }


Input: Checks that all the requested vars exist . If all fills out the param . vars with all grid names Throws exception if some of the variables in the request are not contained in the dataset [CODESPLIT] private void checkRequestedVars ( CoverageCollection gcd , NcssGridParamsBean params ) throws VariableNotContainedInDatasetException { // if var == all --> all variables requested if ( params . getVar ( ) . get ( 0 ) . equalsIgnoreCase ( "all" ) ) { params . setVar ( getAllGridNames ( gcd ) ) ; return ; } // Check vars are contained in the grid for ( String gridName : params . getVar ( ) ) { Coverage grid = gcd . findCoverage ( gridName ) ; if ( grid == null ) throw new VariableNotContainedInDatasetException ( "Variable: " + gridName + " is not contained in the requested dataset" ) ; } }


Input: Returns true if all the variables have the same vertical axis ( if they have an axis ) . Could be broadened to allow all with same coordinate unites? coordinate value?? [CODESPLIT] protected boolean checkVarsHaveSameVertAxis ( CoverageCollection gcd , NcssGridParamsBean params ) { String zaxisName = null ; for ( String gridName : params . getVar ( ) ) { Coverage grid = gcd . findCoverage ( gridName ) ; CoverageCoordAxis zaxis = grid . getCoordSys ( ) . getZAxis ( ) ; if ( zaxis != null ) { if ( zaxisName == null ) zaxisName = zaxis . getName ( ) ; else if ( ! zaxisName . equals ( zaxis . getName ( ) ) ) return false ; } } return true ; }


Input: Construct a Stereographic Projection using latitude of true scale and calculating scale factor . <p > Since the scale factor at lat = k = 2 * k0 / ( 1 + sin ( lat )) [ Snyder Working Manual p157 ] then to make scale = 1 at lat set k0 = ( 1 + sin ( lat )) / 2 [CODESPLIT] static public Stereographic factory ( double latt , double lont , double latTrue ) { double scale = ( 1.0 + Math . sin ( Math . toRadians ( latTrue ) ) ) / 2.0 ; return new Stereographic ( latt , lont , scale ) ; }


Input: Calculate polar stereographic scale factor based on the natural latitude and longitude of the original Ref : OGP Surveying and Positioning Guidance Note number 7 part 2 April 2009 http : // www . epsg . org added by Qun He <qunhe@unc . edu > [CODESPLIT] private double getScaleFactor ( double lat_ts , boolean north ) { double e = 0.081819191 ; double tf = 1.0 , mf = 1.0 , k0 = 1.0 ; double root = ( 1 + e * Math . sin ( lat_ts ) ) / ( 1 - e * Math . sin ( lat_ts ) ) ; double power = e / 2 ; if ( north ) tf = Math . tan ( Math . PI / 4 - lat_ts / 2 ) * ( Math . pow ( root , power ) ) ; else tf = Math . tan ( Math . PI / 4 + lat_ts / 2 ) / ( Math . pow ( root , power ) ) ; mf = Math . cos ( lat_ts ) / Math . sqrt ( 1 - e * e * Math . pow ( Math . sin ( lat_ts ) , 2 ) ) ; k0 = mf * Math . sqrt ( Math . pow ( 1 + e , 1 + e ) * Math . pow ( 1 - e , 1 - e ) ) / ( 2 * tf ) ; return Double . isNaN ( k0 ) ? 1.0 : k0 ; }


Input:
Convert a LatLonPoint to projection coordinates [CODESPLIT] public ProjectionPoint latLonToProj ( LatLonPoint latLon , ProjectionPointImpl result ) { double toX , toY ; double fromLat = latLon . getLatitude ( ) ; double fromLon = latLon . getLongitude ( ) ; double lat = Math . toRadians ( fromLat ) ; double lon = Math . toRadians ( fromLon ) ; // keep away from the singular point
 if ( ( Math . abs ( lat + latt ) <= TOLERANCE ) ) { lat = - latt * ( 1.0 - TOLERANCE ) ; } double sdlon = Math . sin ( lon - lont ) ; double cdlon = Math . cos ( lon - lont ) ; double sinlat = Math . sin ( lat ) ; double coslat = Math . cos ( lat ) ; double k = 2.0 * scale / ( 1.0 + sinlatt * sinlat + coslatt * coslat * cdlon ) ; toX = k * coslat * sdlon ; toY = k * ( coslatt * sinlat - sinlatt * coslat * cdlon ) ; result . setLocation ( toX + falseEasting , toY + falseNorthing ) ; return result ; }


Input: Convert projection coordinates to a LatLonPoint Note : a new object is not created on each call for the return value . [CODESPLIT] public LatLonPoint projToLatLon ( ProjectionPoint world , LatLonPointImpl result ) { double toLat , toLon ; double fromX = world . getX ( ) - falseEasting ; double fromY = world . getY ( ) - falseNorthing ; double phi , lam ; double rho = Math . sqrt ( fromX * fromX + fromY * fromY ) ; double c = 2.0 * Math . atan2 ( rho , 2.0 * scale ) ; double sinc = Math . sin ( c ) ; double cosc = Math . cos ( c ) ; if ( Math . abs ( rho ) < TOLERANCE ) { phi = latt ; } else { phi = Math . asin ( cosc * sinlatt + fromY * sinc * coslatt / rho ) ; } toLat = Math . toDegrees ( phi ) ; if ( ( Math . abs ( fromX ) < TOLERANCE ) && ( Math . abs ( fromY ) < TOLERANCE ) ) { lam = lont ; } else if ( Math . abs ( coslatt ) < TOLERANCE ) { lam = lont + Math . atan2 ( fromX , ( ( latt > 0 ) ? - fromY : fromY ) ) ; } else { lam = lont + Math . atan2 ( fromX * sinc , rho * coslatt * cosc - fromY * sinc * sinlatt ) ; } toLon = Math . toDegrees ( lam ) ; result . setLatitude ( toLat ) ; result . setLongitude ( toLon ) ; return result ; }


Input: Convert projection coordinates to lat / lon coordinate . [CODESPLIT] public float [ ] [ ] projToLatLon ( float [ ] [ ] from , float [ ] [ ] to ) { int cnt = from [ 0 ] . length ; float [ ] fromXA = from [ INDEX_X ] ; float [ ] fromYA = from [ INDEX_Y ] ; float [ ] toLatA = to [ INDEX_LAT ] ; float [ ] toLonA = to [ INDEX_LON ] ; double phi , lam ; double toLat , toLon ; for ( int i = 0 ; i < cnt ; i ++ ) { double fromX = fromXA [ i ] - falseEasting ; double fromY = fromYA [ i ] - falseNorthing ; double rho = Math . sqrt ( fromX * fromX + fromY * fromY ) ; double c = 2.0 * Math . atan2 ( rho , 2.0 * scale ) ; double sinc = Math . sin ( c ) ; double cosc = Math . cos ( c ) ; if ( Math . abs ( rho ) < TOLERANCE ) { phi = latt ; } else { phi = Math . asin ( cosc * sinlatt + fromY * sinc * coslatt / rho ) ; } toLat = Math . toDegrees ( phi ) ; if ( ( Math . abs ( fromX ) < TOLERANCE ) && ( Math . abs ( fromY ) < TOLERANCE ) ) { lam = lont ; } else if ( Math . abs ( coslatt ) < TOLERANCE ) { lam = lont + Math . atan2 ( fromX , ( ( latt > 0 ) ? - fromY : fromY ) ) ; } else { lam = lont + Math . atan2 ( fromX * sinc , rho * coslatt * cosc - fromY * sinc * sinlatt ) ; } toLon = Math . toDegrees ( lam ) ; toLatA [ i ] = ( float ) toLat ; toLonA [ i ] = ( float ) toLon ; } return to ; }


Input:
Convert lat / lon coordinates to projection coordinates . [CODESPLIT] public double [ ] [ ] latLonToProj ( double [ ] [ ] from , double [ ] [ ] to , int latIndex , int lonIndex ) { int cnt = from [ 0 ] . length ; double [ ] fromLatA = from [ latIndex ] ; double [ ] fromLonA = from [ lonIndex ] ; double [ ] resultXA = to [ INDEX_X ] ; double [ ] resultYA = to [ INDEX_Y ] ; double toX , toY ; for ( int i = 0 ; i < cnt ; i ++ ) { double fromLat = fromLatA [ i ] ; double fromLon = fromLonA [ i ] ; double lat = Math . toRadians ( fromLat ) ; double lon = Math . toRadians ( fromLon ) ; // keep away from the singular point
 if ( ( Math . abs ( lat + latt ) <= TOLERANCE ) ) { lat = - latt * ( 1.0 - TOLERANCE ) ; } double sdlon = Math . sin ( lon - lont ) ; double cdlon = Math . cos ( lon - lont ) ; double sinlat = Math . sin ( lat ) ; double coslat = Math . cos ( lat ) ; double k = 2.0 * scale / ( 1.0 + sinlatt * sinlat + coslatt * coslat * cdlon ) ; toX = k * coslat * sdlon ; toY = k * ( coslatt * sinlat - sinlatt * coslat * cdlon ) ; resultXA [ i ] = toX + falseEasting ; resultYA [ i ] = toY + falseNorthing ; } return to ; }


Input: Find the DatasetSourceStructure that matches this name . [CODESPLIT] public static DatasetSourceStructure getStructure ( String name ) { if ( name == null ) return null ; return ( DatasetSourceStructure ) hash . get ( name ) ; }


Input: to work under Intellij . [CODESPLIT] @ Override public String getResourcePath ( DapRequest drq , String location ) throws DapException { String realpath ; if ( TdsRequestedDataset . getDatasetManager ( ) != null ) { realpath = TdsRequestedDataset . getLocationFromRequestPath ( location ) ; } else { assert TdsRequestedDataset . getDatasetManager ( ) == null ; String prefix = drq . getResourceRoot ( ) ; assert ( prefix != null ) ; realpath = DapUtil . canonjoin ( prefix , location ) ; } if ( ! TESTING ) { if ( ! TdsRequestedDataset . resourceControlOk ( drq . getRequest ( ) , drq . getResponse ( ) , realpath ) ) throw new DapException ( "Not authorized: " + location ) . setCode ( DapCodes . SC_FORBIDDEN ) ; } File f = new File ( realpath ) ; if ( ! f . exists ( ) || ! f . canRead ( ) ) throw new DapException ( "Not found: " + location ) . setCode ( DapCodes . SC_NOT_FOUND ) ; //ncfile = TdsRequestedDataset.getNetcdfFile(this.request, this.response, path); return realpath ; }


Input:
Fill in the netCDF file [CODESPLIT] public void open ( GridIndex index , GridTableLookup lookup , int version , NetcdfFile ncfile , CancelTask cancelTask ) throws IOException { // create the HorizCoord Systems : one for each gds List < GridDefRecord > hcsList = index . getHorizCoordSys ( ) ; boolean needGroups = ( hcsList . size ( ) > 1 ) ; for ( GridDefRecord gds : hcsList ) { Group g = null ; if ( needGroups ) { g = new Group ( ncfile , null , gds . getGroupName ( ) ) ; ncfile . addGroup ( null , g ) ; } // (GridDefRecord gdsIndex, String grid_name, String shape_name, Group g) GridHorizCoordSys hcs = makeGridHorizCoordSys ( gds , lookup , g ) ; hcsHash . put ( gds . getParam ( GridDefRecord . GDS_KEY ) , hcs ) ; } // run through each record GridRecord firstRecord = null ; List < GridRecord > records = index . getGridRecords ( ) ; for ( GridRecord gridRecord : records ) { if ( firstRecord == null ) { firstRecord = gridRecord ; } GridHorizCoordSys hcs = hcsHash . get ( gridRecord . getGridDefRecordId ( ) ) ; int cdmHash = gridRecord . cdmVariableHash ( ) ; GridVariable pv = hcs . varHash . get ( cdmHash ) ; if ( null == pv ) { String name = gridRecord . cdmVariableName ( lookup , true , true ) ; pv = makeGridVariable ( indexFilename , name , hcs , lookup ) ; hcs . varHash . put ( cdmHash , pv ) ; // keep track of all products with same parameter name == "simple name" String simpleName = gridRecord . getParameterDescription ( ) ; List < GridVariable > plist = hcs . productHash . get ( simpleName ) ; if ( null == plist ) { plist = new ArrayList <> ( ) ; hcs . productHash . put ( simpleName , plist ) ; } plist . add ( pv ) ; } /* else if ( lookup instanceof Grib2GridTableLookup ) {
        Grib2GridTableLookup g2lookup = (Grib2GridTableLookup) lookup;
        // check for non interval pv and interval record which needs a interval pv
        if( ! pv.isInterval() && g2lookup.isInterval(gridRecord) ) {
          // make an interval variable
          String interval = name +"_interval";
          pv = (GridVariable) hcs.varHash.get(interval);
          if (null == pv) {
            pv = new GridVariable(interval, hcs, lookup);
            hcs.varHash.put(cdmHash, pv);
            String simpleName = makeVariableName(gridRecord, lookup, false, true); // LOOK may not be a good idea
            List<GridVariable> plist = hcs.productHash.get(simpleName);
            if (null == plist) {
              plist = new ArrayList<GridVariable>();
              hcs.productHash.put(simpleName, plist);
            }
            plist.add(pv);
          }

        } else if ( pv.isInterval() && !g2lookup.isInterval(gridRecord)  ) {
          // make a non-interval variable
          // logger.info( "Non-Interval records for %s%n", pv.getName());  LOOK
            continue;
        }
      } // grid2 */ pv . addProduct ( gridRecord ) ; } // global CF Conventions // Conventions attribute change must be in sync with CDM code ncfile . addAttribute ( null , new Attribute ( "Conventions" , "CF-1.4" ) ) ; addExtraAttributes ( firstRecord , lookup , ncfile ) ; // CF Global attributes ncfile . addAttribute ( null , new Attribute ( "title" , lookup . getTitle ( ) ) ) ; if ( lookup . getInstitution ( ) != null ) ncfile . addAttribute ( null , new Attribute ( "institution" , lookup . getInstitution ( ) ) ) ; String source = lookup . getSource ( ) ; if ( source != null && ! source . startsWith ( "Unknown" ) ) ncfile . addAttribute ( null , new Attribute ( "source" , source ) ) ; // String now = formatter.toDateTimeStringISO( Calendar.getInstance().getTime()); ncfile . addAttribute ( null , new Attribute ( "history" , "Direct read of " + lookup . getGridType ( ) + " into NetCDF-Java 4 API" ) ) ; if ( lookup . getComment ( ) != null ) ncfile . addAttribute ( null , new Attribute ( "comment" , lookup . getComment ( ) ) ) ; // dataset discovery //if ( center != null) //  ncfile.addAttribute(null, new Attribute("center_name", center)); // CDM attributes ncfile . addAttribute ( null , new Attribute ( CF . FEATURE_TYPE , FeatureType . GRID . toString ( ) ) ) ; ncfile . addAttribute ( null , new Attribute ( "file_format" , lookup . getGridType ( ) ) ) ; // ncfile.addAttribute(null, new Attribute("location", ncfile.getLocation())); ncfile . addAttribute ( null , new Attribute ( _Coordinate . ModelRunDate , formatter . toDateTimeStringISO ( lookup . getFirstBaseTime ( ) ) ) ) ; /* if (fmrcCoordSys != null) {
      makeDefinedCoordSys(ncfile, lookup, fmrcCoordSys);
    } else {
      makeDenseCoordSys(ncfile, lookup, cancelTask);
    } */ makeDenseCoordSys ( ncfile , lookup , cancelTask ) ; if ( GridServiceProvider . debugMissing ) { try ( Formatter f = new Formatter ( System . out ) ) { int count = 0 ; Collection < GridHorizCoordSys > hcset = hcsHash . values ( ) ; for ( GridHorizCoordSys hcs : hcset ) { List < GridVariable > gribvars = new ArrayList <> ( hcs . varHash . values ( ) ) ; for ( GridVariable gv : gribvars ) { count += gv . showMissingSummary ( f ) ; } } System . out . println ( " total missing= " + count ) ; } } if ( GridServiceProvider . debugMissingDetails ) { Formatter f = new Formatter ( ) ; Collection < GridHorizCoordSys > hcset = hcsHash . values ( ) ; for ( GridHorizCoordSys hcs : hcset ) { f . format ( "******** Horiz Coordinate= %s%n" , hcs . getGridName ( ) ) ; String lastVertDesc = null ; List < GridVariable > gribvars = new ArrayList <> ( hcs . varHash . values ( ) ) ; Collections . sort ( gribvars , new CompareGridVariableByVertName ( ) ) ; for ( GridVariable gv : gribvars ) { String vertDesc = gv . getVertName ( ) ; if ( ! vertDesc . equals ( lastVertDesc ) ) { f . format ( "---Vertical Coordinate= %s%n" , vertDesc ) ; lastVertDesc = vertDesc ; } gv . showMissing ( f ) ; } } } // clean out stuff we dont need anymore //for (GridHorizCoordSys ghcs : hcsHash.values()) { //  ghcs.empty(); //} }


Input: Make coordinate system without missing data - means that we have to make a coordinate axis for each unique set of time or vertical levels . [CODESPLIT] private void makeDenseCoordSys ( NetcdfFile ncfile , GridTableLookup lookup , CancelTask cancelTask ) throws IOException { List < GridTimeCoord > timeCoords = new ArrayList <> ( ) ; List < GridVertCoord > vertCoords = new ArrayList <> ( ) ; List < GridEnsembleCoord > ensembleCoords = new ArrayList <> ( ) ; Calendar calendar = Calendar . getInstance ( ) ; calendar . setTimeZone ( java . util . TimeZone . getTimeZone ( "GMT" ) ) ; // loop over HorizCoordSys Collection < GridHorizCoordSys > hcset = hcsHash . values ( ) ; for ( GridHorizCoordSys hcs : hcset ) { if ( ( cancelTask != null ) && cancelTask . isCancel ( ) ) break ; // loop over GridVariables in the HorizCoordSys // create the time and vertical coordinates List < GridVariable > gribvars = new ArrayList <> ( hcs . varHash . values ( ) ) ; for ( GridVariable gv : gribvars ) { if ( ( cancelTask != null ) && cancelTask . isCancel ( ) ) break ; List < GridRecord > recordList = gv . getRecords ( ) ; GridRecord record = recordList . get ( 0 ) ; String vname = gv . makeLevelName ( record , lookup ) ; // look to see if vertical already exists GridVertCoord useVertCoord = null ; for ( GridVertCoord gvcs : vertCoords ) { if ( vname . equals ( gvcs . getLevelName ( ) ) ) { if ( gvcs . matchLevels ( recordList ) ) { // must have the same levels useVertCoord = gvcs ; } } } if ( useVertCoord == null ) { // nope, got to create it useVertCoord = makeGridVertCoord ( recordList , vname , lookup , hcs ) ; vertCoords . add ( useVertCoord ) ; } gv . setVertCoord ( useVertCoord ) ; // look to see if time coord already exists GridTimeCoord useTimeCoord = null ; for ( GridTimeCoord gtc : timeCoords ) { if ( gtc . matchTimes ( recordList ) ) { // must have the same time coords useTimeCoord = gtc ; break ; } } if ( useTimeCoord == null ) { // nope, got to create it useTimeCoord = makeGridTimeCoord ( recordList , ncfile . getLocation ( ) ) ; timeCoords . add ( useTimeCoord ) ; } gv . setTimeCoord ( useTimeCoord ) ; if ( gv . isEnsemble ( ) ) { GridEnsembleCoord useEnsembleCoord = addEnsembles ( ensembleCoords , recordList ) ; if ( useEnsembleCoord != null ) gv . setEnsembleCoord ( useEnsembleCoord ) ; } } // assign time coordinate names, add dimensions to file // reverse sort by length - give time dimensions unique names Collections . sort ( timeCoords ) ; int count = 0 ; for ( GridTimeCoord tcs : timeCoords ) { tcs . setSequence ( count ++ ) ; tcs . addDimensionsToNetcdfFile ( ncfile , hcs . getGroup ( ) ) ; } // add Ensemble dimensions, give Ensemble dimensions unique names int seqno = 0 ; for ( GridEnsembleCoord gec : ensembleCoords ) { gec . setSequence ( seqno ++ ) ; gec . addDimensionsToNetcdfFile ( ncfile , hcs . getGroup ( ) ) ; } // add x, y dimensions hcs . addDimensionsToNetcdfFile ( ncfile ) ; // add vertical dimensions, give them unique names Collections . sort ( vertCoords ) ; int vcIndex = 0 ; String listName = null ; int start = 0 ; for ( vcIndex = 0 ; vcIndex < vertCoords . size ( ) ; vcIndex ++ ) { GridVertCoord gvcs = vertCoords . get ( vcIndex ) ; String vname = gvcs . getLevelName ( ) ; if ( listName == null ) { listName = vname ; // initial } if ( ! vname . equals ( listName ) ) { makeVerticalDimensions ( vertCoords . subList ( start , vcIndex ) , ncfile , hcs . getGroup ( ) ) ; listName = vname ; start = vcIndex ; } } makeVerticalDimensions ( vertCoords . subList ( start , vcIndex ) , ncfile , hcs . getGroup ( ) ) ; // create a variable for each entry, but check for other products with same simple name to disambiguate List < List < GridVariable > > products = new ArrayList <> ( hcs . productHash . values ( ) ) ; for ( List < GridVariable > plist : products ) { if ( ( cancelTask != null ) && cancelTask . isCancel ( ) ) break ; if ( plist . size ( ) == 1 ) { GridVariable pv = plist . get ( 0 ) ; String name = pv . getFirstRecord ( ) . cdmVariableName ( lookup , false , false ) ; // plain ole name Variable v = pv . makeVariable ( ncfile , hcs . getGroup ( ) , name , raf ) ; ncfile . addVariable ( hcs . getGroup ( ) , v ) ; } else { // collect them grouped by vertical coord Map < GridVertCoord , VertCollection > vcMap = new HashMap <> ( ) ; for ( GridVariable gv : plist ) { VertCollection vc = vcMap . get ( gv . getVertCoord ( ) ) ; if ( vc == null ) { vc = new VertCollection ( gv ) ; vcMap . put ( gv . getVertCoord ( ) , vc ) ; } vc . list . add ( gv ) ; } // sort by larger # vert levels List < VertCollection > vclist = new ArrayList <> ( vcMap . values ( ) ) ; Collections . sort ( vclist ) ; boolean firstVertCoord = true ; for ( VertCollection vc : vclist ) { boolean hasMultipleLevels = vc . vc . getNLevels ( ) > 1 ; boolean noLevelOk = firstVertCoord ; //  && hasMultipleLevels;  LOOK turned off for now 9/15/10 List < GridVariable > list = vc . list ; if ( list . size ( ) == 1 ) { GridVariable gv = list . get ( 0 ) ; String name = gv . getFirstRecord ( ) . cdmVariableName ( lookup , ! noLevelOk , false ) ; ncfile . addVariable ( hcs . getGroup ( ) , gv . makeVariable ( ncfile , hcs . getGroup ( ) , name , raf ) ) ; } else { for ( GridVariable gv : list ) { // more than one - disambiguate by stat name String name = gv . getFirstRecord ( ) . cdmVariableName ( lookup , ! noLevelOk , true ) ; ncfile . addVariable ( hcs . getGroup ( ) , gv . makeVariable ( ncfile , hcs . getGroup ( ) , name , raf ) ) ; } } firstVertCoord = false ; } } // multiple vertical levels } // create variable // add coordinate variables at the end for ( GridTimeCoord tcs : timeCoords ) { tcs . addToNetcdfFile ( ncfile , hcs . getGroup ( ) ) ; } for ( GridEnsembleCoord ens : ensembleCoords ) { ens . addToNetcdfFile ( ncfile , hcs . getGroup ( ) ) ; } hcs . addToNetcdfFile ( ncfile ) ; for ( GridVertCoord gvcs : vertCoords ) { gvcs . addToNetcdfFile ( ncfile , hcs . getGroup ( ) ) ; } } // loop over hcs // TODO: check this,  in ToolsUI it caused problems //for (GridVertCoord gvcs : vertCoords) { //  gvcs.empty(); //} }


Input: Make a vertical dimensions [CODESPLIT] private void makeVerticalDimensions ( List < GridVertCoord > vertCoordList , NetcdfFile ncfile , Group group ) { // find biggest vert coord GridVertCoord gvcs0 = null ; int maxLevels = 0 ; for ( GridVertCoord gvcs : vertCoordList ) { if ( gvcs . getNLevels ( ) > maxLevels ) { gvcs0 = gvcs ; maxLevels = gvcs . getNLevels ( ) ; } } int seqno = 1 ; for ( GridVertCoord gvcs : vertCoordList ) { if ( gvcs != gvcs0 ) { gvcs . setSequence ( seqno ++ ) ; } gvcs . addDimensionsToNetcdfFile ( ncfile , group ) ; } }


Input: Read the header and populate the ncfile [CODESPLIT] boolean readPIB ( RandomAccessFile raf ) throws IOException { this . firstHeader = new AwxFileFirstHeader ( ) ; int pos = 0 ; raf . seek ( pos ) ; // gini header process byte [ ] buf = new byte [ FY_AWX_PIB_LEN ] ; int count = raf . read ( buf ) ; EndianByteBuffer byteBuffer ; if ( count == FY_AWX_PIB_LEN ) { byteBuffer = new EndianByteBuffer ( buf , this . firstHeader . byteOrder ) ; this . firstHeader . fillHeader ( byteBuffer ) ; } else { return false ; } if ( ! ( ( this . firstHeader . fileName . endsWith ( ".AWX" ) || this . firstHeader . fileName . endsWith ( ".awx" ) ) && this . firstHeader . firstHeaderLength == FY_AWX_PIB_LEN ) ) { return false ; } // skip the fills of the first record //  raf.seek(FY_AWX_PIB_LEN + this.firstHeader.fillSectionLength); buf = new byte [ this . firstHeader . secondHeaderLength ] ; raf . readFully ( buf ) ; byteBuffer = new EndianByteBuffer ( buf , this . firstHeader . byteOrder ) ; switch ( this . firstHeader . typeOfProduct ) { case AwxFileFirstHeader . AWX_PRODUCT_TYPE_UNDEFINED : throw new UnsupportedDatasetException ( ) ; case AwxFileFirstHeader . AWX_PRODUCT_TYPE_GEOSAT_IMAGE : secondHeader = new AwxFileGeoSatelliteSecondHeader ( ) ; secondHeader . fillHeader ( byteBuffer ) ; break ; case AwxFileFirstHeader . AWX_PRODUCT_TYPE_POLARSAT_IMAGE : throw new UnsupportedDatasetException ( ) ; case AwxFileFirstHeader . AWX_PRODUCT_TYPE_GRID : secondHeader = new AwxFileGridProductSecondHeader ( ) ; secondHeader . fillHeader ( byteBuffer ) ; break ; case AwxFileFirstHeader . AWX_PRODUCT_TYPE_DISCREET : throw new UnsupportedDatasetException ( ) ; case AwxFileFirstHeader . AWX_PRODUCT_TYPE_GRAPH_ANALIYSIS : throw new UnsupportedDatasetException ( ) ; } return true ; }


Input: Finish constructing after all elements have been added . This does the inheritence thing This can be called again if new elements are added . [CODESPLIT] public boolean finish ( ) { boolean ok = true ; java . util . Iterator iter ; logger . debug ( "Now finish " + getName ( ) + " id= " + getID ( ) ) ; authorityName = null ; dataType = null ; dataFormatType = null ; defaultService = null ; gc = null ; tc = null ; docs = new ArrayList <> ( ) ; metadata = new ArrayList <> ( ) ; properties = new ArrayList <> ( ) ; creators = new ArrayList <> ( ) ; contributors = new ArrayList <> ( ) ; dates = new ArrayList <> ( ) ; keywords = new ArrayList <> ( ) ; projects = new ArrayList <> ( ) ; publishers = new ArrayList <> ( ) ; variables = new ArrayList <> ( ) ; canonicalize ( ) ; // canonicalize thredds metadata transfer2PublicMetadata ( tm , true ) ; // add local metadata transfer2PublicMetadata ( tmi , true ) ; // add local inherited metadata transferInheritable2PublicMetadata ( ( InvDatasetImpl ) getParent ( ) ) ; // add inheritable metadata from parents // build the expanded access list access = new ArrayList <> ( ) ; // add access element if urlPath is specified if ( ( urlPath != null ) && ( getServiceDefault ( ) != null ) ) { InvAccessImpl a = new InvAccessImpl ( this , urlPath , getServiceDefault ( ) ) ; a . setSize ( size ) ; a . finish ( ) ; addExpandedAccess ( a ) ; } // add local access elements iter = accessLocal . iterator ( ) ; while ( iter . hasNext ( ) ) { InvAccessImpl a = ( InvAccessImpl ) iter . next ( ) ; a . finish ( ) ; addExpandedAccess ( a ) ; } // recurse into child datasets. if ( ! ( this instanceof InvCatalogRef ) ) { for ( InvDataset invDataset : this . getDatasets ( ) ) { InvDatasetImpl curDs = ( InvDatasetImpl ) invDataset ; ok &= curDs . finish ( ) ; } } return ok ; }


Input:
Look for InvMetadata elements in the parent that need to be added to the public metadata of this dataset . Recurse up through all ancestors . [CODESPLIT] private void transferInheritable2PublicMetadata ( InvDatasetImpl parent ) { if ( parent == null ) return ; logger . debug ( " inheritFromParent= " + parent . getID ( ) ) ; transfer2PublicMetadata ( parent . getLocalMetadataInheritable ( ) , true ) ; //transfer2PublicMetadata(parent.getCat6Metadata(), true); /* look through local metadata, find inherited InvMetadata elements
    ThreddsMetadata tmd = parent.getLocalMetadata();
    Iterator iter = tmd.getMetadata().iterator();
    while (iter.hasNext()) {
      InvMetadata meta = (InvMetadata) iter.next();
      if (meta.isInherited()) {
        if (!meta.isThreddsMetadata()) {
          metadata.add(meta);
        } else {
          if (debugInherit) System.out.println("  inheritMetadata Element " + tmd.isInherited() + " " + meta.isInherited());
          meta.finish(); // make sure XLink is read in.
          transfer2PublicMetadata(meta.getThreddsMetadata(), false);
        }
      }
    } */ // recurse transferInheritable2PublicMetadata ( ( InvDatasetImpl ) parent . getParent ( ) ) ; }


Input: take all elements from tmd and add to the public metadata of this dataset . for InvMetadata elements only add if inheritAll || InvMetadata . isInherited () . [CODESPLIT] private void transfer2PublicMetadata ( ThreddsMetadata tmd , boolean inheritAll ) { if ( tmd == null ) return ; logger . debug ( "  transferMetadata " + tmd ) ; if ( authorityName == null ) authorityName = tmd . getAuthority ( ) ; if ( dataType == null || ( dataType == FeatureType . ANY ) ) dataType = tmd . getDataType ( ) ; if ( dataFormatType == null || dataFormatType == DataFormatType . NONE ) dataFormatType = tmd . getDataFormatType ( ) ; if ( defaultService == null ) defaultService = findService ( tmd . getServiceName ( ) ) ; if ( gc == null ) { ThreddsMetadata . GeospatialCoverage tgc = tmd . getGeospatialCoverage ( ) ; if ( ( tgc != null ) && ! tgc . isEmpty ( ) ) gc = tgc ; } if ( tc == null ) { DateRange ttc = tmd . getTimeCoverage ( ) ; if ( ttc != null ) { tc = ttc ; } } if ( tc == null ) tc = tmd . getTimeCoverage ( ) ; for ( InvProperty item : tmd . getProperties ( ) ) { logger . debug ( "  add Property " + item + " to " + getID ( ) ) ; properties . add ( item ) ; } creators . addAll ( tmd . getCreators ( ) ) ; contributors . addAll ( tmd . getContributors ( ) ) ; dates . addAll ( tmd . getDates ( ) ) ; docs . addAll ( tmd . getDocumentation ( ) ) ; keywords . addAll ( tmd . getKeywords ( ) ) ; projects . addAll ( tmd . getProjects ( ) ) ; publishers . addAll ( tmd . getPublishers ( ) ) ; variables . addAll ( tmd . getVariables ( ) ) ; if ( variableMapLink == null ) variableMapLink = tmd . variableMapLink ; for ( InvMetadata meta : tmd . getMetadata ( ) ) { if ( meta . isInherited ( ) || inheritAll ) { if ( ! meta . isThreddsMetadata ( ) ) { metadata . add ( meta ) ; } else { logger . debug ( "  add metadata Element " + tmd . isInherited ( ) + " " + meta ) ; meta . finish ( ) ; // make sure XLink is read in. transfer2PublicMetadata ( meta . getThreddsMetadata ( ) , inheritAll ) ; metadata . add ( meta ) ; } } } }


Input: Transfer all inheritable metadata from fromDs to the local metadata of this dataset . Called by InvDatasetScan to transfer inheritable metaddata to the nested catalogRef [CODESPLIT] public void transferMetadata ( InvDatasetImpl fromDs , boolean copyInheritedMetadataFromParents ) { if ( fromDs == null ) return ; logger . debug ( " transferMetadata= " + fromDs . getName ( ) ) ; if ( this != fromDs ) getLocalMetadata ( ) . add ( fromDs . getLocalMetadata ( ) , false ) ; transferInheritableMetadata ( fromDs , getLocalMetadataInheritable ( ) , copyInheritedMetadataFromParents ) ; setResourceControl ( fromDs . getRestrictAccess ( ) ) ; }


Input:
transfer inherited metadata consolidating it into target [CODESPLIT] private void transferInheritableMetadata ( InvDatasetImpl fromDs , ThreddsMetadata target , boolean copyInheritedMetadataFromParents ) { if ( fromDs == null ) return ; logger . debug ( " transferInheritedMetadata= " + fromDs . getName ( ) ) ; target . add ( fromDs . getLocalMetadataInheritable ( ) , true ) ; /* look through local metadata, find inherited InvMetadata elements
    ThreddsMetadata tmd = fromDs.getLocalMetadata();
    Iterator iter = tmd.getMetadata().iterator();
    while (iter.hasNext()) {
      InvMetadata meta = (InvMetadata) iter.next();
      if (meta.isInherited()) {
        if (!meta.isThreddsMetadata()) {
          tmc.addMetadata( meta);
        } else {
          logger.debug("  transferInheritedMetadata "+meta.hashCode()+" = "+meta);
          meta.finish(); // LOOK ?? make sure XLink is read in.
          tmc.add( meta.getThreddsMetadata(), true);
        }
      }
    }   */ // now do the same for the parents if ( copyInheritedMetadataFromParents ) transferInheritableMetadata ( ( InvDatasetImpl ) fromDs . getParent ( ) , target , true ) ; }


Input: Put metadata into canonical form . All non - inherited thredds metadata put into single metadata element pointed to by getLocalMetadata () . All inherited thredds metadata put into single metadata element pointed to by getLocalMetadataInherited () . This is needed to do reliable editing . [CODESPLIT] protected void canonicalize ( ) { List < InvMetadata > whatsLeft = new ArrayList <> ( ) ; List < InvMetadata > original = new ArrayList <> ( tm . metadata ) ; // get copy of metadata tm . metadata = new ArrayList <> ( ) ; // transfer all non-inherited thredds metadata to tm // transfer all inherited thredds metadata to tmi for ( InvMetadata m : original ) { if ( m . isThreddsMetadata ( ) && ! m . isInherited ( ) && ! m . hasXlink ( ) ) { ThreddsMetadata nested = m . getThreddsMetadata ( ) ; tm . add ( nested , false ) ; } else if ( m . isThreddsMetadata ( ) && m . isInherited ( ) && ! m . hasXlink ( ) ) { ThreddsMetadata nested = m . getThreddsMetadata ( ) ; tmi . add ( nested , true ) ; } else { whatsLeft . add ( m ) ; } } // non ThreddsMetadata goes into tm tm . metadata . addAll ( whatsLeft ) ; }


Input: LOOK these are wrong [CODESPLIT] public void setContributors ( List < ThreddsMetadata . Contributor > a ) { List < ThreddsMetadata . Contributor > dest = tm . getContributors ( ) ; for ( ThreddsMetadata . Contributor item : a ) { if ( ! dest . contains ( item ) ) dest . add ( item ) ; } hashCode = 0 ; }


Input: Add a nested dataset at the location indicated by index . [CODESPLIT] public void addDataset ( int index , InvDatasetImpl ds ) { if ( ds == null ) return ; ds . setParent ( this ) ; datasets . add ( index , ds ) ; hashCode = 0 ; }


Input: Remove the given dataset element from this dataset if it is in the dataset . [CODESPLIT] public boolean removeDataset ( InvDatasetImpl ds ) { if ( this . datasets . remove ( ds ) ) { ds . setParent ( null ) ; InvCatalogImpl cat = ( InvCatalogImpl ) getParentCatalog ( ) ; if ( cat != null ) cat . removeDatasetByID ( ds ) ; return ( true ) ; } return ( false ) ; }


Input: Replace the given dataset if it is a nesetd dataset . [CODESPLIT] public boolean replaceDataset ( InvDatasetImpl remove , InvDatasetImpl add ) { for ( int i = 0 ; i < datasets . size ( ) ; i ++ ) { InvDataset dataset = datasets . get ( i ) ; if ( dataset . equals ( remove ) ) { datasets . set ( i , add ) ; InvCatalogImpl cat = ( InvCatalogImpl ) getParentCatalog ( ) ; if ( cat != null ) { cat . removeDatasetByID ( remove ) ; cat . addDatasetByID ( add ) ; } return true ; } } return false ; }


Input: Add a service to this dataset . [CODESPLIT] public void addService ( InvService service ) { // System.out.println("--add dataset service= "+service.getName()); servicesLocal . add ( service ) ; services . add ( service ) ; // add nested servers for ( InvService nested : service . getServices ( ) ) { services . add ( nested ) ; // System.out.println("--add expanded service= "+nested.getName()); } hashCode = 0 ; }


Input: Remove a service from this dataset . [CODESPLIT] public void removeService ( InvService service ) { servicesLocal . remove ( service ) ; services . remove ( service ) ; // remove nested servers for ( InvService nested : service . getServices ( ) ) { services . remove ( nested ) ; } }


Input: Set the list of services attached specifically to this dataset . Discard any previous servies . [CODESPLIT] public void setServicesLocal ( java . util . List < InvService > s ) { this . services = new ArrayList <> ( ) ; this . servicesLocal = new ArrayList <> ( ) ; for ( InvService elem : s ) { addService ( elem ) ; } hashCode = 0 ; }


Input: Remove the given InvMetadata from the set of metadata local to this dataset . [CODESPLIT] public boolean removeLocalMetadata ( InvMetadata metadata ) { InvDatasetImpl parentDataset = ( ( InvDatasetImpl ) metadata . getParentDataset ( ) ) ; List localMdata = parentDataset . getLocalMetadata ( ) . getMetadata ( ) ; if ( localMdata . contains ( metadata ) ) { if ( localMdata . remove ( metadata ) ) { hashCode = 0 ; // Need to recalculate the hash code. return ( true ) ; } } return ( false ) ; }


Input: Look up the User property having the given key [CODESPLIT] public Object getUserProperty ( Object key ) { if ( userMap == null ) return null ; return userMap . get ( key ) ; }