cdm/src/main/java/ucar/nc2/ft2/simpgeometry/CFLine.java
public Line setupLine(NetcdfDataset dataset, Variable var, int index)
	{
		this.points.clear();
		Array xPts = null;
		Array yPts = null;
		Variable nodeCounts = null;
		Variable partNodeCounts = null;

		List<CoordinateAxis> axes = dataset.getCoordinateAxes();
		CoordinateAxis x = null; CoordinateAxis y = null;
		
		String[] nodeCoords = var.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 node_c_str = var.findAttValueIgnoreCase(CF.NODE_COUNT, "");
		
		if(!node_c_str.equals("")) {
			nodeCounts = dataset.findVariable(node_c_str);
		}
		
		else return null;
		
		// Affirm part node counts
		String pNodeCoStr = var.findAttValueIgnoreCase(CF.PART_NODE_COUNT, "");
		
		if(!pNodeCoStr.equals("")) {
			partNodeCounts = dataset.findVariable(pNodeCoStr);
		}
		
		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;
				
				// x and y should have the same shape, will add some handling on this
				while(itrX.hasNext()) {
					this.addPoint(itrX.getDoubleNext(), itrY.getDoubleNext());
				}
	
				switch(var.getRank()) {
				
				case 2:
					this.setData(var.read(CFSimpleGeometryHelper.getSubsetString(var, index)).reduce());
					break;
					
				case 1:
					this.setData(var.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 {
				
				Line tail = this;
				Array pnc = partNodeCounts.read();
				IndexIterator pncItr = pnc.getIndexIterator();
				
				// 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);
					
					while(smaller > 0) {
						tail.addPoint(itrX.getDoubleNext(), itrY.getDoubleNext());
						smaller--;
					}
					
					// Set data of each	
					switch(var.getRank()) {
					
					case 2:
						tail.setData(var.read(CFSimpleGeometryHelper.getSubsetString(var, index)).reduce());
						break;
						
					case 1:
						tail.setData(var.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 CFLine());
					tail = tail.getNext();
				}
				
				//Clean up
				tail = tail.getPrev();
				if(tail != null) tail.setNext(null);
			}
		}
		
		catch (IOException  | InvalidRangeException  | InvalidDataseriesException e) {
			cfl.error(e.getMessage());;
			return null;
		}
		
		return this;
	}
public Line setupLine(NetcdfDataset dataset, Variable var, int index)
	{
		this.points.clear();
		Array xPts = null;
		Array yPts = null;
		Variable nodeCounts = null;
		Variable partNodeCounts = null;

		List<CoordinateAxis> axes = dataset.getCoordinateAxes();
		CoordinateAxis x = null; CoordinateAxis y = null;
		
		String[] nodeCoords = var.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 node_c_str = var.findAttValueIgnoreCase(CF.NODE_COUNT, "");
		
		if(!node_c_str.equals("")) {
			nodeCounts = dataset.findVariable(node_c_str);
		}
		
		else return null;
		
		// Affirm part node counts
		String pNodeCoStr = var.findAttValueIgnoreCase(CF.PART_NODE_COUNT, "");
		
		if(!pNodeCoStr.equals("")) {
			partNodeCounts = dataset.findVariable(pNodeCoStr);
		}
		
		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;
				
				// x and y should have the same shape, will add some handling on this
				while(itrX.hasNext()) {
					this.addPoint(itrX.getDoubleNext(), itrY.getDoubleNext());
				}
	
				switch(var.getRank()) {
				
				case 2:
					this.setData(var.read(CFSimpleGeometryHelper.getSubsetString(var, index)).reduce());
					break;
					
				case 1:
					this.setData(var.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 {
				
				Line tail = this;
				Array pnc = partNodeCounts.read();
				IndexIterator pncItr = pnc.getIndexIterator();
				
				// 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);
					
					while(smaller > 0) {
						tail.addPoint(itrX.getDoubleNext(), itrY.getDoubleNext());
						smaller--;
					}
					
					// Set data of each	
					switch(var.getRank()) {
					
					case 2:
						tail.setData(var.read(CFSimpleGeometryHelper.getSubsetString(var, index)).reduce());
						break;
						
					case 1:
						tail.setData(var.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 CFLine());
					tail = tail.getNext();
				}
				
				//Clean up
				tail = tail.getPrev();
				if(tail != null) tail.setNext(null);
			}
		}
		
		catch (IOException  | InvalidRangeException  | InvalidDataseriesException e) {
			cfl.error(e.getMessage());;
			return null;
		}
		
		return this;
	}
public Line setupLine ( NetcdfDataset dataset , Variable var , int index ) { this . points . clear ( ) ; Array xPts = null ; Array yPts = null ; Variable nodeCounts = null ; Variable partNodeCounts = null ; List < CoordinateAxis > axes = dataset . getCoordinateAxes ( ) ; CoordinateAxis x = null ; CoordinateAxis y = null ; String [ ] nodeCoords = var . 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 node_c_str = var . findAttValueIgnoreCase ( CF . NODE_COUNT , "" ) ; if ( ! node_c_str . equals ( "" ) ) { nodeCounts = dataset . findVariable ( node_c_str ) ; } else return null ; // Affirm part node counts
 String pNodeCoStr = var . findAttValueIgnoreCase ( CF . PART_NODE_COUNT , "" ) ; if ( ! pNodeCoStr . equals ( "" ) ) { partNodeCounts = dataset . findVariable ( pNodeCoStr ) ; } 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 ; // x and y should have the same shape, will add some handling on this
 while ( itrX . hasNext ( ) ) { this . addPoint ( itrX . getDoubleNext ( ) , itrY . getDoubleNext ( ) ) ; } switch ( var . getRank ( ) ) { case 2 : this . setData ( var . read ( CFSimpleGeometryHelper . getSubsetString ( var , index ) ) . reduce ( ) ) ; break ; case 1 : this . setData ( var . 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 { Line tail = this ; Array pnc = partNodeCounts . read ( ) ; IndexIterator pncItr = pnc . getIndexIterator ( ) ; // 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 ) ; while ( smaller > 0 ) { tail . addPoint ( itrX . getDoubleNext ( ) , itrY . getDoubleNext ( ) ) ; smaller -- ; } // Set data of each	
 switch ( var . getRank ( ) ) { case 2 : tail . setData ( var . read ( CFSimpleGeometryHelper . getSubsetString ( var , index ) ) . reduce ( ) ) ; break ; case 1 : tail . setData ( var . 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 CFLine ( ) ) ; tail = tail . getNext ( ) ; } //Clean up
 tail = tail . getPrev ( ) ; if ( tail != null ) tail . setNext ( null ) ; } } catch ( IOException | InvalidRangeException | InvalidDataseriesException e ) { cfl . error ( e . getMessage ( ) ) ; ; return null ; } return this ; }
Given a dataset, variable, and index, automatically populates this Line and
returns it. If not found, returns null.

@param dataset which the variable is a part of
@param var the variable which has a geometry attribute
@param index of the line within the variable
@return return a line
Given a dataset variable and index automatically populates this Line and returns it . If not found returns null .