cdm/src/main/java/ucar/nc2/ft2/simpgeometry/CFPolygon.java
public Polygon setupPolygon(NetcdfDataset dataset, Variable polyvar, int index)
	{
		this.points.clear();
		Array xPts = null;
		Array yPts = null;
		Variable nodeCounts = null;
		Variable partNodeCounts = null;
		Variable interiorRings = null;

		List<CoordinateAxis> axes = dataset.getCoordinateAxes();
		CoordinateAxis x = null; CoordinateAxis y = null;
		
		String[] nodeCoords = polyvar.findAttributeIgnoreCase(CF.NODE_COORDINATES).getStringValue().split(" ");
		
		// Look for x and y
		
		for(CoordinateAxis ax : axes){
			
			if(ax.getFullName().equals(nodeCoords[0])) x = ax;
			if(ax.getFullName().equals(nodeCoords[1])) y = ax;
		}
		
		// Affirm node counts
		String nodeCoStr = polyvar.findAttValueIgnoreCase(CF.NODE_COUNT, "");
		
		if(!nodeCoStr.equals("")) {
			nodeCounts = dataset.findVariable(nodeCoStr);
		}
		
		else return null;
		
		// Affirm part node counts
		String pNodeCoStr = polyvar.findAttValueIgnoreCase(CF.PART_NODE_COUNT, "");
		
		if(!pNodeCoStr.equals("")) {
			partNodeCounts = dataset.findVariable(pNodeCoStr);
		}
		
		// Affirm interior rings
		String interiorRingsStr = polyvar.findAttValueIgnoreCase(CF.PART_NODE_COUNT, "");
				
		if(!interiorRingsStr.equals("")) {
				interiorRings = dataset.findVariable(interiorRingsStr);
		}
		
		SimpleGeometryIndexFinder indexFinder = new SimpleGeometryIndexFinder(nodeCounts);
		
		//Get beginning and ending indicies for this polygon
		int lower = indexFinder.getBeginning(index);
		int upper = indexFinder.getEnd(index);

		
		try {
			
			xPts = x.read( lower + ":" + upper ).reduce();
			yPts = y.read( lower + ":" + upper ).reduce(); 

			IndexIterator itrX = xPts.getIndexIterator();
			IndexIterator itrY = yPts.getIndexIterator();
			
			// No multipolygons just read in the whole thing
			if(partNodeCounts == null) {
				
				this.next = null;
				this.prev = null;
				this.isInteriorRing = false;
				
				// x and y should have the same shape, will add some handling on this
				while(itrX.hasNext()) {
					this.addPoint(itrX.getDoubleNext(), itrY.getDoubleNext());
				}
	
				
				switch(polyvar.getRank()) {
				
				case 2:
					this.setData(polyvar.read(CFSimpleGeometryHelper.getSubsetString(polyvar, index)).reduce());
					break;
					
				case 1:
					this.setData(polyvar.read("" + index));
					break;
					
				default:
					throw new InvalidDataseriesException(InvalidDataseriesException.RANK_MISMATCH);	// currently do not support anything but dataseries and scalar associations
				
				}
			}
			
			// If there are multipolygons then take the upper and lower of it and divy it up
			else {
				
				Polygon tail = this;
				Array pnc = partNodeCounts.read();
				Array ir = null;
				IndexIterator pncItr = pnc.getIndexIterator();
				
				if(interiorRings != null) ir = interiorRings.read();
				
				// In part node count search for the right index to begin looking for "part node counts"
				int pncInd = 0;
				int pncEnd = 0;
				while(pncEnd < lower)
				{
					pncEnd += pncItr.getIntNext();
					pncInd++;
				}
				
				// Now the index is found, use part node count and the index to find each part node count of each individual part
				while(lower < upper) {
					
					int smaller = pnc.getInt(pncInd);
					
					// Set interior ring if needed
					if(interiorRings != null)
					{
						int interiorRingValue = ir.getInt(pncInd);
						
						switch(interiorRingValue) {
						
							case 0:
								this.setInteriorRing(false);
								break;
								
							case 1:
								this.setInteriorRing(true);
								break;
								
							// will handle default case
						}
						
					} else this.isInteriorRing = false;
					
					while(smaller > 0) {
						tail.addPoint(itrX.getDoubleNext(), itrY.getDoubleNext());
						smaller--;
					}
					
					// Set data of each
					switch(polyvar.getRank()) {
					
					case 2:
						tail.setData(polyvar.read(CFSimpleGeometryHelper.getSubsetString(polyvar, index)).reduce());
						break;
						
					case 1:
						tail.setData(polyvar.read("" + index));
						break;
						
					default:
						throw new InvalidDataseriesException(InvalidDataseriesException.RANK_MISMATCH);	// currently do not support anything but dataseries and scalar associations
					
					}

					lower += tail.getPoints().size();
					pncInd++;
					tail.setNext(new CFPolygon());
					tail = tail.getNext();
				}
				
				//Clean up
				tail = tail.getPrev();
				if(tail != null) tail.setNext(null);
			}
		}
		
		catch (IOException | InvalidRangeException | InvalidDataseriesException e) {
			cfpl.error(e.getMessage());
			return null;
		}
		
		return this;
	}
public Polygon setupPolygon(NetcdfDataset dataset, Variable polyvar, int index)
	{
		this.points.clear();
		Array xPts = null;
		Array yPts = null;
		Variable nodeCounts = null;
		Variable partNodeCounts = null;
		Variable interiorRings = null;

		List<CoordinateAxis> axes = dataset.getCoordinateAxes();
		CoordinateAxis x = null; CoordinateAxis y = null;
		
		String[] nodeCoords = polyvar.findAttributeIgnoreCase(CF.NODE_COORDINATES).getStringValue().split(" ");
		
		// Look for x and y
		
		for(CoordinateAxis ax : axes){
			
			if(ax.getFullName().equals(nodeCoords[0])) x = ax;
			if(ax.getFullName().equals(nodeCoords[1])) y = ax;
		}
		
		// Affirm node counts
		String nodeCoStr = polyvar.findAttValueIgnoreCase(CF.NODE_COUNT, "");
		
		if(!nodeCoStr.equals("")) {
			nodeCounts = dataset.findVariable(nodeCoStr);
		}
		
		else return null;
		
		// Affirm part node counts
		String pNodeCoStr = polyvar.findAttValueIgnoreCase(CF.PART_NODE_COUNT, "");
		
		if(!pNodeCoStr.equals("")) {
			partNodeCounts = dataset.findVariable(pNodeCoStr);
		}
		
		// Affirm interior rings
		String interiorRingsStr = polyvar.findAttValueIgnoreCase(CF.PART_NODE_COUNT, "");
				
		if(!interiorRingsStr.equals("")) {
				interiorRings = dataset.findVariable(interiorRingsStr);
		}
		
		SimpleGeometryIndexFinder indexFinder = new SimpleGeometryIndexFinder(nodeCounts);
		
		//Get beginning and ending indicies for this polygon
		int lower = indexFinder.getBeginning(index);
		int upper = indexFinder.getEnd(index);

		
		try {
			
			xPts = x.read( lower + ":" + upper ).reduce();
			yPts = y.read( lower + ":" + upper ).reduce(); 

			IndexIterator itrX = xPts.getIndexIterator();
			IndexIterator itrY = yPts.getIndexIterator();
			
			// No multipolygons just read in the whole thing
			if(partNodeCounts == null) {
				
				this.next = null;
				this.prev = null;
				this.isInteriorRing = false;
				
				// x and y should have the same shape, will add some handling on this
				while(itrX.hasNext()) {
					this.addPoint(itrX.getDoubleNext(), itrY.getDoubleNext());
				}
	
				
				switch(polyvar.getRank()) {
				
				case 2:
					this.setData(polyvar.read(CFSimpleGeometryHelper.getSubsetString(polyvar, index)).reduce());
					break;
					
				case 1:
					this.setData(polyvar.read("" + index));
					break;
					
				default:
					throw new InvalidDataseriesException(InvalidDataseriesException.RANK_MISMATCH);	// currently do not support anything but dataseries and scalar associations
				
				}
			}
			
			// If there are multipolygons then take the upper and lower of it and divy it up
			else {
				
				Polygon tail = this;
				Array pnc = partNodeCounts.read();
				Array ir = null;
				IndexIterator pncItr = pnc.getIndexIterator();
				
				if(interiorRings != null) ir = interiorRings.read();
				
				// In part node count search for the right index to begin looking for "part node counts"
				int pncInd = 0;
				int pncEnd = 0;
				while(pncEnd < lower)
				{
					pncEnd += pncItr.getIntNext();
					pncInd++;
				}
				
				// Now the index is found, use part node count and the index to find each part node count of each individual part
				while(lower < upper) {
					
					int smaller = pnc.getInt(pncInd);
					
					// Set interior ring if needed
					if(interiorRings != null)
					{
						int interiorRingValue = ir.getInt(pncInd);
						
						switch(interiorRingValue) {
						
							case 0:
								this.setInteriorRing(false);
								break;
								
							case 1:
								this.setInteriorRing(true);
								break;
								
							// will handle default case
						}
						
					} else this.isInteriorRing = false;
					
					while(smaller > 0) {
						tail.addPoint(itrX.getDoubleNext(), itrY.getDoubleNext());
						smaller--;
					}
					
					// Set data of each
					switch(polyvar.getRank()) {
					
					case 2:
						tail.setData(polyvar.read(CFSimpleGeometryHelper.getSubsetString(polyvar, index)).reduce());
						break;
						
					case 1:
						tail.setData(polyvar.read("" + index));
						break;
						
					default:
						throw new InvalidDataseriesException(InvalidDataseriesException.RANK_MISMATCH);	// currently do not support anything but dataseries and scalar associations
					
					}

					lower += tail.getPoints().size();
					pncInd++;
					tail.setNext(new CFPolygon());
					tail = tail.getNext();
				}
				
				//Clean up
				tail = tail.getPrev();
				if(tail != null) tail.setNext(null);
			}
		}
		
		catch (IOException | InvalidRangeException | InvalidDataseriesException e) {
			cfpl.error(e.getMessage());
			return null;
		}
		
		return this;
	}
public Polygon setupPolygon ( NetcdfDataset dataset , Variable polyvar , int index ) { this . points . clear ( ) ; Array xPts = null ; Array yPts = null ; Variable nodeCounts = null ; Variable partNodeCounts = null ; Variable interiorRings = null ; List < CoordinateAxis > axes = dataset . getCoordinateAxes ( ) ; CoordinateAxis x = null ; CoordinateAxis y = null ; String [ ] nodeCoords = polyvar . findAttributeIgnoreCase ( CF . NODE_COORDINATES ) . getStringValue ( ) . split ( " " ) ; // Look for x and y
 for ( CoordinateAxis ax : axes ) { if ( ax . getFullName ( ) . equals ( nodeCoords [ 0 ] ) ) x = ax ; if ( ax . getFullName ( ) . equals ( nodeCoords [ 1 ] ) ) y = ax ; } // Affirm node counts
 String nodeCoStr = polyvar . findAttValueIgnoreCase ( CF . NODE_COUNT , "" ) ; if ( ! nodeCoStr . equals ( "" ) ) { nodeCounts = dataset . findVariable ( nodeCoStr ) ; } else return null ; // Affirm part node counts
 String pNodeCoStr = polyvar . findAttValueIgnoreCase ( CF . PART_NODE_COUNT , "" ) ; if ( ! pNodeCoStr . equals ( "" ) ) { partNodeCounts = dataset . findVariable ( pNodeCoStr ) ; } // Affirm interior rings
 String interiorRingsStr = polyvar . findAttValueIgnoreCase ( CF . PART_NODE_COUNT , "" ) ; if ( ! interiorRingsStr . equals ( "" ) ) { interiorRings = dataset . findVariable ( interiorRingsStr ) ; } SimpleGeometryIndexFinder indexFinder = new SimpleGeometryIndexFinder ( nodeCounts ) ; //Get beginning and ending indicies for this polygon
 int lower = indexFinder . getBeginning ( index ) ; int upper = indexFinder . getEnd ( index ) ; try { xPts = x . read ( lower + ":" + upper ) . reduce ( ) ; yPts = y . read ( lower + ":" + upper ) . reduce ( ) ; IndexIterator itrX = xPts . getIndexIterator ( ) ; IndexIterator itrY = yPts . getIndexIterator ( ) ; // No multipolygons just read in the whole thing
 if ( partNodeCounts == null ) { this . next = null ; this . prev = null ; this . isInteriorRing = false ; // x and y should have the same shape, will add some handling on this
 while ( itrX . hasNext ( ) ) { this . addPoint ( itrX . getDoubleNext ( ) , itrY . getDoubleNext ( ) ) ; } switch ( polyvar . getRank ( ) ) { case 2 : this . setData ( polyvar . read ( CFSimpleGeometryHelper . getSubsetString ( polyvar , index ) ) . reduce ( ) ) ; break ; case 1 : this . setData ( polyvar . read ( "" + index ) ) ; break ; default : throw new InvalidDataseriesException ( InvalidDataseriesException . RANK_MISMATCH ) ; // currently do not support anything but dataseries and scalar associations
 } } // If there are multipolygons then take the upper and lower of it and divy it up
 else { Polygon tail = this ; Array pnc = partNodeCounts . read ( ) ; Array ir = null ; IndexIterator pncItr = pnc . getIndexIterator ( ) ; if ( interiorRings != null ) ir = interiorRings . read ( ) ; // In part node count search for the right index to begin looking for "part node counts"
 int pncInd = 0 ; int pncEnd = 0 ; while ( pncEnd < lower ) { pncEnd += pncItr . getIntNext ( ) ; pncInd ++ ; } // Now the index is found, use part node count and the index to find each part node count of each individual part
 while ( lower < upper ) { int smaller = pnc . getInt ( pncInd ) ; // Set interior ring if needed
 if ( interiorRings != null ) { int interiorRingValue = ir . getInt ( pncInd ) ; switch ( interiorRingValue ) { case 0 : this . setInteriorRing ( false ) ; break ; case 1 : this . setInteriorRing ( true ) ; break ; // will handle default case
 } } else this . isInteriorRing = false ; while ( smaller > 0 ) { tail . addPoint ( itrX . getDoubleNext ( ) , itrY . getDoubleNext ( ) ) ; smaller -- ; } // Set data of each
 switch ( polyvar . getRank ( ) ) { case 2 : tail . setData ( polyvar . read ( CFSimpleGeometryHelper . getSubsetString ( polyvar , index ) ) . reduce ( ) ) ; break ; case 1 : tail . setData ( polyvar . read ( "" + index ) ) ; break ; default : throw new InvalidDataseriesException ( InvalidDataseriesException . RANK_MISMATCH ) ; // currently do not support anything but dataseries and scalar associations
 } lower += tail . getPoints ( ) . size ( ) ; pncInd ++ ; tail . setNext ( new CFPolygon ( ) ) ; tail = tail . getNext ( ) ; } //Clean up
 tail = tail . getPrev ( ) ; if ( tail != null ) tail . setNext ( null ) ; } } catch ( IOException | InvalidRangeException | InvalidDataseriesException e ) { cfpl . error ( e . getMessage ( ) ) ; return null ; } return this ; }
Given a dataset, variable and index, automatically sets up a previously constructed polygon.
If the specified polygon is not found in the dataset, returns null

@param dataset which the variable is a part of
@param polyvar the variable which has a geometry attribute
@param index of the polygon within the variable
Given a dataset variable and index automatically sets up a previously constructed polygon . If the specified polygon is not found in the dataset returns null