# ------------------------------------------------------------ # OBJECT.sml # ------------------------------------------------------------ # SET WARNING LEVEL: $warnings 3 # ------------------------------------------------------------ # COMPUTE-WATERSHED FUNCTION flag STRING ASSIGNMENT: # See ComputeWatershed SML Function for More Complex Options. string computeW$ = "Ridge"; # ------------------------------------------------------------ # DEFINE STRING VARIABLES FOR POPUP FUNCTION PROMPTS: string p$,p1$,p2$,p3$,p4$,p5$,p6$; # ------------------------------------------------------------ # DEFINE PROCEDURE writeTitle: proc writeTitle() begin printf("DRAFT OBJECT.sml:\n"); printf(" VERSION: May 4, 2006\n"); printf(" PURPOSE: PRODUCE SCENE-OBJECT "); printf("POLYGONS (SOPs).\n"); printf(" FROM AN INPUT IMAGE RASTER.\n"); printf(" DETAILS: FAQs_by_Jack H"); printf(" AUTHOR: Dr. Jack F. Paris\n"); printf(" CONTACT INFO: jparis37@msn.com "); printf(" 303-775-1195\n"); printf(" ALLOWED USE: ONLY NON-COMMERCIAL\n\n"); end # ------------------------------------------------------------ # CLEAR CONSOLE WINDOW & ALLOW USER TO REPOSITION IT: clear(); p1$ = "CONSOLE-WINDOW ADJUSTMENT\n"; p2$ = "* IF NECESSARY, REPOSITION the CONSOLE WINDOW.\n"; p3$ = "* Then, CLICK the OK Button."; p$ = p1$ + p2$ + p3$; PopupMessage(p$); # ------------------------------------------------------------ # DECLARE VARIABLES, RASTER OBJECTS, and VECTOR OBJECTS: class DATABASE db; class DBTABLEINFO table; class WATERSHED w; string rObjFileName$,rFilePath$,rFile$,rObj$,rinObj$; string fNameEP$,fNameW$,fNameSOP$,fNameDum$,desc$; string fNameEP2$; string epFile$,epObj$,vNameW$,vOptsW$,wFile$,wObj$; string rtype$,eptype$,vtopo$,tname$,tdesc$,f1$,f2$; numeric err,rObj,epObj,linscale,colscale; numeric optEP; numeric floorRin,ceilRin,minEP,eLen,cPTLinD,fThin,aIPMin; numeric lin,col,nlins,ncols,linm1,linp1,colm1,colp1; numeric linbegin,linend,colbegin,colend,i; numeric hnRin,nvRin,minRin,maxRin,vR; numeric r1,r2,r3,r4,r6,r7,r8,r9; numeric s1,s2,s3,s4,s5,s6,s7,s8,s9,slope; numeric rflag,rg1,rg2,rg3,rg4,ravg,cIso; numeric gradx,grady,gradmag; numeric vEP,vEPold,aminEP,amaxEP,epLin,epFac; numeric delPar,delParMin,delParMax; numeric fqsum,cfq,cf10,cf20,cf30,cf40,cf50; numeric cf60,cf70,cf80,cf90,cfU; numeric maxEP,eLenp1; numeric aIPL,aIPR,aIPv,nodeS,nodeE; numeric numE,numEM,nvpolys,nvlins; numeric nL,pL,pR,medL,medR,medMin,medMax,medOff,medOff2; numeric maxmed,ccL,ccR; numeric ccMin,lenL,lenLMax,wObj; raster Rin,R,EP,EP2,Dum; vector WATERSHED,SOP; # ------------------------------------------------------------ # DEFINE proc checkHisto(Band) # PURPOSE: Ensures that Input Raster Has Unsampled Histogram. proc checkHisto (raster Band) begin local numeric sampleInt; sampleInt = HistogramGetSampleInterval(Band); if (sampleInt > 1) begin DeleteHistogram(Band); CreateHistogram(Band,0); end else if (sampleInt == -1) then begin CreateHistogram(Band,0); end end # ------------------------------------------------------------ # WRITE TITLE & AUTHOR INFORMATION: writeTitle(); # ------------------------------------------------------------ # GET AN INPUT RASTER, Rin: printf("GOOD CHOICES FOR Rin: Any Tasseled Cap Raster"); printf(" or Any SRFI Raster\n\n"); GetInputRaster(Rin); nlins = NumLins(Rin); minRin = GlobalMin(Rin); maxRin = GlobalMax(Rin); rFile$ = GetObjectFileName(Rin); rObj = GetObjectNumber(Rin); rinObj$ = GetObjectName(rFile$,rObj); ncols = NumCols(Rin); rtype$ = RastType(Rin); checkHisto(Rin); linscale = LinScale(Rin); colscale = ColScale(Rin); hnRin = HasNull(Rin); if (hnRin == 1) then nvRin = NullValue(Rin); # ------------------------------------------------------------ # OPTION: CONTINUE WITH AN EXISTING EP RASTER # OR: CREATE A NEW EP RASTER: p1$ = "EP RASTER OPTION:\n"; p2$ = " 1: CREATE a NEW EP Raster\n"; p3$ = " 2: CONTINUE with an EXISTING EP Raster\n"; p4$ = "OPTION ENTERED:"; p$ = p1$ + p2$ + p3$ + p4$; optEP = PopupNum(p$,1,1,2,0); # ------------------------------------------------------------ # DEFINE VARIOUS FILE & PATH STRINGS USED IN THIS SCRIPT: rObjFileName$ = GetObjectFileName(Rin); rFilePath$ = FileNameGetPath(rObjFileName$); fNameEP$ = rFilePath$ + "\\EP.rvc"; fNameDum$ = rFilePath$ + "\\DUMMY.rvc"; fNameW$ = rFilePath$ + "\\WATERSHED.rvc"; fNameSOP$ = rFilePath$ + "\\SOP.rvc"; # ------------------------------------------------------------ # PRINT INFORMATION ABOUT RASTER Rin TO CONSOLE WINDOW: printf("INPUT RASTER, Rin, INFORMATION:\n"); printf(" Raster Name: %s\n",rinObj$); printf(" Data Range: From "); printf("%6d to %5d\n",minRin,maxRin); printf(" Line Spacing: %5.2f m ",linscale); printf("Column Spacing: %5.2f m\n\n",colscale); # ------------------------------------------------------------ # INITIAL VALUES FOR USER-SPECIFIED CONTROL-PARAMETERS: floorRin = minRin; ceilRin = maxRin; minEP = 1; eLen = 1; cPTLinD = 0; fThin = 0; aIPMin = 1; medOff = 0; # ------------------------------------------------------------ # DEFINITIONS OF CONTROL PARAMETERS: # floorRin = LOWEST ALLOWED VALUE for RASTER Rin # ceilRin = HIGHEST ALLOWED VALUE for RASTER Rin # minEP = THE MINIMUM ALLOWED VALUE FOR RASTER EP # eLen = THE NUMBER OF CELLS FOR INTERPOLATION # cPTLinD = CUMULATIVE-PERCENTILE FOR LINE DELETION # fThin = THE VECTOR-LINE THINNING PARAMETER # aIPMin = SMALLEST ALLOWED AREA FOR ISLAND POLYGONS # medOff = ADDED OFFSET FOR SOP MEDIAN VALUES # ------------------------------------------------------------ # USER INPUTS FOR CONTROL PARAMETERS: # floorRin: p1$ = "INPUT-RASTER FLOOR-VALUE:\n"; p2$ = " DEFAULT = MINIMUM VALUE OF RASTER Rin\n"; p3$ = " IF PURPOSE IS TO DEFINE VEG OBJECTS:\n"; p4$ = " THEN USE TC2 AS Rin AND\n"; p5$ = " CHANGE VALUE NEAR ZERO.\n"; p6$ = "VALUE ENTERED:"; p$ = p1$ + p2$ + p3$ + p4$ + p5$ + p6$; floorRin = PopupNum(p$,floorRin,minRin,maxRin,0); # ceilRin: p1$ = "INPUT-RASTER CEILING-VALUE:\n"; p2$ = " DEFAULT = MAXIMUM VALUE OF RASTER Rin\n"; p3$ = " IF PURPOSE IS TO DEFINE VEG OBJECTS:\n"; p4$ = " THEN USE TC2 AS Rin AND\n"; p5$ = " CHANGE VALUE NEAR 2000.\n"; p6$ = "VALUE ENTERED:"; p$ = p1$ + p2$ + p3$ + p4$ + p5$ + p6$; ceilRin = PopupNum(p$,ceilRin,minRin,maxRin,0); # minEP: p1$ = "MINIMUM ALLOWED EDGE-PROBABILITY VALUE:\n"; p2$ = " RANGE: 1 to 5000\n"; p3$ = "VALUE ENTERED:"; p$ = p1$ + p2$ + p3$; minEP = PopupNum(p$,minEP,1,5000,0); maxEP = 10000; # eLen: p1$ = "EXTRAPOLATION-LINE LENGTH:\n"; p2$ = " RANGE: 1 to 9\n"; p3$ = " LIMIT: MUST BE AN ODD INTEGER\n"; p4$ = " NOTE: ENTER 1 FOR NO EXTRAPOLATION.\n"; p5$ = " PURPOSE: SMOOTHING & INTERPOLATION\n"; p6$ = "VALUE ENTERED:"; p$ = p1$ + p2$ + p3$ + p4$ + p5$ +p6$; eLen = PopupNum(p$,eLen,1,9,0); if (eLen > 2) then begin eLen = 2 * int(eLen / 2) + 1; end eLenp1 = eLen + 1; # cPTLinD: if (optEP == 1) then begin p1$ = "CUMULATIVE-PERCENTILE FOR LINE DELETION:\n"; p2$ = " RANGE: 0 to 100 (percent)\n"; p3$ = " NOTE: ENTER 0 FOR NO DELETION.\n"; p3$ = "VALUE ENTERED:"; p$ = p1$ + p2$ + p3$; cPTLinD = PopupNum(p$,cPTLinD,0,100,0); end if (optEP == 2) then cPTLinD = 0; # fThin: p1$ = "VECTOR-LINE THINNING-FACTOR:\n"; p2$ = " RANGE: 0.00 to 3.00\n"; p3$ = " NOTE: If < 0.2, NO THINNING.\n"; p4$ = "VALUE ENTERED:"; p$ = p1$ + p2$ + p3$ + p4$; fThin = PopupNum(p$,fThin,0,3,2); # aIPMin: p1$ = "MINIMUM ISLAND-POLYGON AREA:\n"; p2$ = " RANGE: 1 to 1 million sq. m.\n"; p3$ = "VALUE ENTERED:"; p$ = p1$ + p2$ + p3$; aIPMin = PopupNum(p$,aIPMin,1,1000000,0); # medOff: if (cPTLinD > 0) then begin if (optEP == 1) then begin p1$ = "OFFSET FOR SOP MEDIAN VALUES:\n"; p2$ = " RANGE: 0 to 10000\n"; p3$ = "VALUE ENTERED:"; p$ = p1$ + p2$ + p3$; medOff = PopupNum(p$,medOff,0,10000,0); end end # ------------------------------------------------------------ # PRINT USER-SELECTABLE PARAMETERS TO CONSOLE WINDOW: printf("USER-SELECTABLE CONTROL PARAMETER VALUES:\n"); printf(" floorRin: %7d\n",floorRin); printf(" ceilRin: %7d\n",ceilRin); printf(" minEP: %7d\n",minEP); printf(" eLen: %7d (cells)\n",eLen); if (optEP == 1) then begin printf(" cPTLinD: %10.2f (percentile)\n",cPTLinD); end printf(" fThin: %10.2f\n",fThin); printf(" aIPMin: %7d (sq. m.)\n",aIPMin); if (cPTLinD > 0) then begin if (optEP == 1) then begin printf(" medOff: %7d\n",medOff); end end printf("\n"); # ------------------------------------------------------------ # CREATE TEMPORARY RASTER, R, WHICH IS A COPY OF Rin: CreateTempRaster(R,nlins,ncols,rtype$); if (hnRin == 1) then IgnoreNull(Rin); IgnoreNull(R); for each R begin vR = Rin; R = vR; end CopySubobjects(Rin,R,"GEOREF"); if (hnRin == 1) then begin SetNull(Rin,nvRin); DeleteHistogram(Rin); CreateHistogram(Rin,0); end rFile$ = GetObjectFileName(R); rObj = GetObjectNumber(R); rObj$ = GetObjectName(rFile$,rObj); # ------------------------------------------------------------ # SET RASTER R VALUE TO floorRin OR TO ceilRin: numE = 0; for each R begin vR = R; if (vR < floorRin) then begin R = floorRin; numE = numE + 1; end if (vR > ceilRin) then begin R = ceilRin; numE = numE + 1; end end DeleteHistogram(R); CreateHistogram(R,0); printf("NUMBER OF RASTER R PIXELS CHANGED: %d\n",numE); # ------------------------------------------------------------ # CREATE A NEW EDGE-PROBABILITIES (EP) RASTER: desc$ = "Based on " + rinObj$; eptype$ = "16-bit unsigned"; if (optEP == 2) then begin GetInputRaster(EP,nlins,ncols,eptype$); printf("SCRIPT CONTINUES WITH AN EXISTING EP RASTER.\n"); end else begin CreateRaster(EP,fNameEP$,"EP",desc$,nlins,ncols,eptype$); printf("SCRIPT STARTS WITH A NEW EP RASTER.\n"); CopySubobjects(R,EP,"GEOREF"); end epFile$ = GetObjectFileName(EP); epObj = GetObjectNumber(EP); epObj$ = GetObjectName(epFile$,epObj); CreateRaster(Dum,fNameDum$,"Dum","",1,1,"8-bit unsigned"); DeleteObject(fNameDum$,1); PackRVC(fNameDum$); CreateRaster(EP2,fNameDum$,"EP2","",nlins,ncols,eptype$); EP2 = minEP; # ------------------------------------------------------------ # CREATE A NEW SCENE-OBJECT-POLYGONS (SOP) VECTOR: desc$ = "Scene-Object-Polygons"; CreateVector(SOP,fNameSOP$,"SOP",desc$,"VectorToolkit"); # ------------------------------------------------------------ # SET UP ARRAYS & PARAMETERS FOR EDGE-PROBABILITY PROCESS: if (eLen == 1) then begin eLen = 2; eLenp1 = 3; end array numeric x[eLenp1]; array numeric y[eLenp1]; linbegin = eLen + 1; colbegin = eLen + 1; linend = nlins - eLen; colend = ncols - eLen; for i=1 to eLen begin x[i] = i - 1; end # ------------------------------------------------------------ # SOBEL STAR CONFIGURATION: xx: MARKS RELATIVE POSITIONS # OF THE EXTENDED "STAR" CELLS USED TO EXTRAPOLATE TO # THE SOBEL 3 by 3 FILTER ELEMENTS. # # THE SOBEL-STAR CONFIGURATION BELOW IS FOR eLen = 3. # # xx xx xx # # xx xx xx # # r1 r2 r3 # # xx xx r4 cc r6 xx xx # # r7 r8 r9 # # xx xx xx # # xx xx xx # # ------------------------------------------------------------ # SCAN THE IMAGE TO FIND amaxEP: printf("SCANNING TO FIND THE MAXIMUM EP VALUE ... "); amaxEP = 0; for lin = linbegin to linend begin for col = colbegin to colend begin # ESTIMATE VALUE (BY EXTRAPOLATION) AT CELL r1: for i=1 to eLen y[i] = R[(lin-i),(col-i)]; slope = LinearRegression(x,y,eLen,s1,r1); # ESTIMATE VALUE (BY EXTRAPOLATION) AT CELL r2: for i=1 to eLen y[i] = R[(lin-i),col]; slope = LinearRegression(x,y,eLen,s2,r2); # ESTIMATE VALUE (BY EXTRAPOLATION) AT CELL r3: for i=1 to eLen y[i] = R[(lin-i),(col+i)]; slope = LinearRegression(x,y,eLen,s3,r3); # ESTIMATE VALUE (BY EXTRAPOLATION) AT CELL r4: for i=1 to eLen y[i] = R[lin,(col-i)]; slope = LinearRegression(x,y,eLen,s4,r4); # ESTIMATE VALUE (BY EXTRAPOLATION) AT CELL r6: for i=1 to eLen y[i] = R[lin,(col+i)]; slope = LinearRegression(x,y,eLen,s6,r6); # ESTIMATE VALUE (BY EXTRAPOLATION) AT CELL r7: for i=1 to eLen y[i] = R[(lin+i),(col-i)]; slope = LinearRegression(x,y,eLen,s7,r7); # ESTIMATE VALUE (BY EXTRAPOLATION) AT CELL r8: for i=1 to eLen y[i] = R[(lin+i),col]; slope = LinearRegression(x,y,eLen,s8,r8); # ESTIMATE VALUE (BY EXTRAPOLATION) AT CELL r9: for i=1 to eLen y[i] = R[(lin+i),(col+i)]; slope = LinearRegression(x,y,eLen,s9,r9); # gradx (Spacing-Corrected Sobel 3 by 3 ALGORITHM): gradx = r3 + 2*r6 + r9 - (r1 + 2*r4 + r7); gradx = gradx / (8 * colscale); # grady (Spacing-Corrected Sobel 3 by 3 ALGORITHM): grady = r7 + 2*r8 + r9 - (r1 + 2*r2 + r3); grady = grady / (8 * linscale); # vEP (Absolute Gradiant Vector Magnitude): vEP = sqrt(gradx*gradx + grady*grady); if (vEP > amaxEP) then amaxEP = vEP; end end printf("Done\n\n"); epFac = maxEP / amaxEP; printf("RESULTS OF EP SCAN:\n"); printf(" Before being scaled up by epFac:\n"); printf(" aminEP = %7.2f amaxEP = %10.2f\n",aminEP,amaxEP); printf(" epFac = %7.2f\n\n",epFac); # ------------------------------------------------------------ # PROCESS RASTER R TO PRODUCE EDGE-PROBABILITY (EP) VALUES: printf("PRODUCING FINAL VALUES FOR EP RASTER ... "); aminEP = 2^16; amaxEP = 0; for lin = linbegin to linend begin for col = colbegin to colend begin for i=1 to eLen y[i] = R[(lin-i),(col-i)]; slope = LinearRegression(x,y,eLen,s1,r1); for i=1 to eLen y[i] = R[(lin-i),col]; slope = LinearRegression(x,y,eLen,s2,r2); for i=1 to eLen y[i] = R[(lin-i),(col+i)]; slope = LinearRegression(x,y,eLen,s3,r3); for i=1 to eLen y[i] = R[lin,(col-i)]; slope = LinearRegression(x,y,eLen,s4,r4); for i=1 to eLen y[i] = R[lin,(col+i)]; slope = LinearRegression(x,y,eLen,s6,r6); for i=1 to eLen y[i] = R[(lin+i),(col-i)]; slope = LinearRegression(x,y,eLen,s7,r7); for i=1 to eLen y[i] = R[(lin+i),col]; slope = LinearRegression(x,y,eLen,s8,r8); for i=1 to eLen y[i] = R[(lin+i),(col+i)]; slope = LinearRegression(x,y,eLen,s9,r9); gradx = r3 + 2*r6 + r9 - (r1 + 2*r4 + r7); gradx = gradx / (8 * colscale); grady = r7 + 2*r8 + r9 - (r1 + 2*r2 + r3); grady = grady / (8 * linscale); gradmag = sqrt(gradx*gradx + grady*grady); vEP = ceil(epFac * gradmag); if (vEP < aminEP) then aminEP = vEP; if (vEP > amaxEP) then amaxEP = vEP; vEP = Bound(vEP,minEP,maxEP); if (optEP == 2) then begin vEPold = EP[lin,col]; if (vEP > vEPold) then begin EP[lin,col] = vEP; end end else EP[lin,col] = vEP; end end # ------------------------------------------------------------ # FIND AND REPLACE ISOLATED EP CELLS THAT HAVE VALUES = minEP. # REPLACEMENT VALUE IS THE MAXIMUM OF THE FOUR AVERAGES # OF OPPOSING CELLS (HORIZONTAL, VERTICAL & THE TWO DIAGONALS): cIso = 0; for lin = linbegin to linend begin for col = colbegin to colend begin vEP = EP[lin,col]; if (vEP == minEP) then begin rflag = 0; rg1 = 0; rg2 = 0; rg3 = 0; rg4 = 0; linm1 = lin - 1; linp1 = lin + 1; colm1 = col - 1; colp1 = colp1; r1 = EP[linm1,colm1]; r9 = EP[linp1,colp1]; if (r1 > minEP and r9 > minEP) then begin rflag = 1; rg1 = (r1 + r9) / 2; end r2 = EP[linm1,col]; r8 = EP[linp1,col]; if (r2 > minEP and r8 > minEP) then begin rflag = 1; rg2 = (r2 + r8) / 2; end r3 = EP[linm1,colp1]; r7 = EP[linp1,colm1]; if (r3 > minEP and r7 > minEP) then begin rflag = 1; rg3 = (r3 + r7) / 2; end r4 = EP[lin,colm1]; r6 = EP[lin,colp1]; if (r4 > minEP and r6 > minEP) then begin rflag = 1; rg4 = (r4 + r6) / 2; end if (rflag == 1) then begin ravg = SetMax(rg1,rg2,rg3,rg4); EP[lin,col] = ceil(ravg); cIso = cIso + 1; end end end end if (eLen == 2) then eLen = 1; for lin = linbegin to linend begin for col = colbegin to colend begin EP2[lin,col] = FocalMax(EP,eLen,eLen,lin,col,1); end end # TRANSFER FILTERED EP2 VALUES TO EP RASTER: EP = EP2; printf("Done\n"); printf("RASTER EP INFORMATION:\n"); printf(" EP RANGE: From %4d to %7d\n",minEP,maxEP); printf(" Isolated EP Cells (Changed): %d\n\n",cIso); IgnoreNull(EP); DeleteHistogram(EP); CreateHistogram(EP,0); # ------------------------------------------------------------ # ASSIGN HANDLE (w) to EP RASTER: # NOTE: EP is treated as a "DEM" so that the TNTmips # WATERSHED processes can be used to produce # Scene-Object Polygons (i.e., "WATERSHEDS"). w = WatershedInit(epFile$,epObj$); # ------------------------------------------------------------ # PROCESS RASTER EP TO MAKE SCENE-OBJECT POLYGONS (SOPs): printf("PROCESSING RASTER EP TO PRODUCE POLYGONS:\n"); printf(" Making Scene-Object Polygons (SOPs) .... "); WatershedCompute(w,computeW$); printf("Done\n"); printf(" Saving SOPs to WATERSHED Vector ........ "); WatershedGetObject(w,"VectorWatershed",wFile$,wObj$); wObj = ObjectNumber(wFile$,wObj$,"Vector"); CopyObject(wFile$,wObj,fNameDum$); WatershedClose(w); CreateHistogram(EP,0); CreatePyramid(EP,0); CloseRaster(EP); CloseRaster(EP2); printf("Done\n\n"); # ------------------------------------------------------------ # RE-OPEN VECTOR OBJECT, WATERSHED, FOR FURTHER PROCESSING: vNameW$ = "WATERSHED"; vOptsW$ = "VectorToolkit"; OpenVector(WATERSHED,fNameDum$,vNameW$,vOptsW$); numEM = WATERSHED.$Info.NumPoints; # ------------------------------------------------------------ # DELETE POUR POINTS FROM WATERSHED VECTOR OBJECT: array numeric ptlist[numEM + 1]; for numE=1 to numEM begin ptlist[numE] = numE; end if (numEM > 0) then begin VectorDeletePoints(WATERSHED,ptlist,numEM); end # ------------------------------------------------------------ # COPY WATERSHED VECTOR ELEMENTS TO VECTOR OBJECT SOP: nvlins = WATERSHED.$Info.NumLines; nvpolys = WATERSHED.$Info.NumPolys; VectorCopyElements(WATERSHED,SOP); CloseVector(WATERSHED); # ------------------------------------------------------------ # DELETE LARGE POLYGON AROUND THE OUTSIDE EDGE OF RASTER EP: numeric polyNum, numPolyMaxArea, area, maxArea; for polyNum=1 to nvpolys begin area = SOP.poly[polyNum].POLYSTATS.Area; if (area > maxArea) begin maxArea = area; numPolyMaxArea = polyNum; end end if (SOP.Poly[numPolyMaxArea].Internal.MinX == 0 and SOP.Poly[numPolyMaxArea].Internal.MinY == 0) then VectorDeletePoly(SOP, numPolyMaxArea); # ------------------------------------------------------------ # BUILD POLYGONS FROM MODIFIED LINES: printf("BUILDING INITIAL SOPs IN VECTOR SOP ....... "); VectorValidate(SOP); printf("Done\n"); # ------------------------------------------------------------ # MAKE A REPORT CONCERNING VECTOR SOP's ELEMENTS: nvpolys = SOP.$Info.NumPolys; nvlins = SOP.$Info.NumLines; printf(" Polygons: %d",nvpolys); printf(" Lines: %d\n\n",nvlins); printf("REMAINING PROCESSING STEPS"); printf(" STATUS\n"); # ------------------------------------------------------------ # COMPUTE RASTER PROPERTIES (FROM R) FOR R_Props TABLE: tname$ = "R_Props"; tdesc$ = "R Attributes"; f1$ = "Proportionality"; f2$ = "NULL"; array numeric delLlist[nvlins]; # ------------------------------------------------------------ if (optEP == 1) then begin # START PROCESS TO COMBINE & CLEAN UP SIMILAR SOPs: printf(" CREATING R_Props DATABASE TABLE ........ "); ComputeRasterProperties(Rin,SOP,tname$,tdesc$,f1$,f2$); printf("Done\n "); if (cPTLinD > 0) then begin # PROCESS TO DELETE LINES BETWEEN SIMILAR SOPs: # DETERMINE RANGE OF DELETION PARAMETER (delPar): printf("DETERMINING RANGES ..................... "); medMin = 100000; medMax = -100000; for nL=1 to nvlins begin pL = SOP.line[nL].Internal.LeftPoly; pR = SOP.line[nL].Internal.RightPoly; if (pL > 0 and pR > 0) then begin ccL = SOP.poly[pL].R_Props.CellCount; ccR = SOP.poly[pR].R_Props.CellCount; ccMin = SetMin(ccL,ccR); if (ccMin > 5) then begin medL = SOP.poly[pL].R_Props.Median; medR = SOP.poly[pR].R_Props.Median; if (medL < medMin) then medMin = medL; if (medL > medMax) then medMax = medL; if (medR < medMin) then medMin = medR; if (medR > medMax) then medMax = medR; end end end medOff2 = medOff - medMin + 10; delParMin = 100000; delParMax = -100000; for nL = 1 to nvlins begin pL = SOP.line[nL].Internal.LeftPoly; pR = SOP.line[nL].Internal.RightPoly; if (pL > 0 and pR > 0) then begin ccL = SOP.poly[pL].R_Props.CellCount; ccR = SOP.poly[pR].R_Props.CellCount; ccMin = SetMin(ccL,ccR); if (ccMin > 5) then begin medL = SOP.poly[pL].R_Props.Median; medR = SOP.poly[pR].R_Props.Median; medL = medL + medOff2; medR = medR + medOff2; delPar = abs((medL - medR) / (medL + medR)); delPar = round(10000 * delPar); if (delPar < delParMin) then delParMin = delPar; if (delPar > delParMax) then delParMax = delPar; end end end printf("Done\n"); printf(" Polygon Rin Median Range: %6d",medMin); printf(" to %6d\n",medMax); printf(" delPar Range: %7d",delParMin); printf(" to %7d\n",delParMax); # CALCULATE CUMULATIVE DISTRIBUTION OF delPar VALUES: array numeric fq[delParMax + 1]; # CALCULATE RAW FREQUENCY DISTRIBUTION (fq[i]): for nL = 1 to nvlins begin pL = SOP.line[nL].Internal.LeftPoly; pR = SOP.line[nL].Internal.RightPoly; if (pL > 0 and pR > 0) then begin ccL = SOP.poly[pL].R_Props.CellCount; ccR = SOP.poly[pR].R_Props.CellCount; ccMin = SetMin(ccL,ccR); if (ccMin > 5) then begin medL = SOP.poly[pL].R_Props.Median; medR = SOP.poly[pR].R_Props.Median; medL = medL + medOff2; medR = medR + medOff2; delPar = abs((medL - medR) / (medL + medR)); delPar = round(10000 * delPar); fq[delPar] = fq[delPar] + 1; end end end fqsum = 0; # CALCULATE SUM OF RAW FREQUENCY VALUES: for i=0 to delParMax begin fqsum = fqsum + fq[i]; end # CALCULATE CUMULATIVE FREQUENCY DISTRIBUTION: cfq = 0; cf10 = 0; cf20 = 0; cf30 = 0; cf40 = 0; cf50 = 0; cf60 = 0; cf70 = 0; cf80 = 0; cfU = 0; for i=0 to delParMax begin cfq = cfq + fq[i] / fqsum; fq[i] = 100 * cfq; if (cfU == 0) then begin if (fq[i] >= cPTLinD) then cfU = i; end if (cf10 == 0) then begin if (fq[i] >= 10) then cf10 = i; end if (cf20 == 0) then begin if (fq[i] >= 20) then cf20 = i; end if (cf30 == 0) then begin if (fq[i] >= 30) then cf30 = i; end if (cf40 == 0) then begin if (fq[i] >= 40) then cf40 = i; end if (cf50 == 0) then begin if (fq[i] >= 50) then cf50 = i; end if (cf60 == 0) then begin if (fq[i] >= 60) then cf60 = i; end if (cf70 == 0) then begin if (fq[i] >= 70) then cf70 = i; end if (cf80 == 0) then begin if (fq[i] >= 80) then cf80 = i; end if (cf90 == 0) then begin if (fq[i] >= 90) then cf90 = i; end end # PRINTOUT CUMULATIVE FREQUENCY DISTRIBUTION DATA: printf(" delPar at %4.1f Percentile:",cPTLinD); printf(" %d \n",cfU); printf(" CUMULATIVE DISTRIBUTION OF delPar:\n"); printf(" cfq delPar\n"); printf(" 10%9d\n",cf10); printf(" 20%9d\n",cf20); printf(" 30%9d\n",cf30); printf(" 40%9d\n",cf40); printf(" 50%9d\n",cf50); printf(" 60%9d\n",cf60); printf(" 70%9d\n",cf70); printf(" 80%9d\n",cf80); printf(" 90%9d\n",cf90); # BEGIN PROCESS TO DELETE WEAK POLYLINES: printf(" FINDING WEAK EDGES ..................... "); for nL=1 to nvlins begin delLlist[nL] = 0; end numEM = 0; for nL = 1 to nvlins begin pL = SOP.line[nL].Internal.LeftPoly; pR = SOP.line[nL].Internal.RightPoly; if (pL > 0 and pR > 0) then begin ccL = SOP.poly[pL].R_Props.CellCount; ccR = SOP.poly[pR].R_Props.CellCount; ccMin = SetMin(ccL,ccR); if (ccMin > 5) then begin medL = SOP.poly[pL].R_Props.Median; medR = SOP.poly[pR].R_Props.Median; medL = medL + medOff2; medR = medR + medOff2; delPar = abs((medL - medR) / (medL + medR)); delPar = round(10000 * delPar); if (delPar < cfU) then begin numEM = numEM + 1; delLlist[numEM] = nL; end end end end printf("Done\n "); printf("COMBINING SOPs THAT ARE ALIKE .......... "); if (numEM > 0) then begin VectorDeleteLines(SOP,delLlist,numEM); end printf("Done\n "); # (RE)BUILD SOPs: printf("(RE)BUILDING SOPs ...................... "); VectorValidate(SOP); printf("Done\n "); end # BEGIN PROCESS TO DELETE DANGLING LINES: lenLMax = 0; nvlins = SOP.$Info.NumLines; for nL=1 to nvlins begin lenL = SOP.line[nL].LINESTATS.Length; if (lenL > lenLMax) then lenLMax = lenL; end lenLMax = lenLMax + 1; printf("DELETING DANGLING LINES IN SOP ......... "); VectorDeleteDangleLines(SOP,lenLMax); printf("Done\n "); # RE-BUILD SOPs: printf("(RE)BUILDING SOPs ...................... "); VectorValidate(SOP); printf("Done\n"); end # ------------------------------------------------------------ # DELETE LINES ASSOCIATED WITH SMALL ISLAND POLYGONS in SOP: printf(" FINDING ISLAND-POLYGONS TO DELETE ...... "); nvlins = SOP.$Info.NumLines; # RE-SET delLlist ARRAY VALUES TO ZERO: for numE=1 to nvlins begin delLlist[numE] = 0; end numEM = 0; # LINES ASSOCIATED WITH ISLAND POLYGONS USE SAME NODE NUMBER # FOR START NODE AND ENDING NODE: for nL=1 to nvlins begin nodeS = SOP.line[nL].Internal.StartNode; nodeE = SOP.line[nL].Internal.EndNode; # FIND AREA OF SMALLER RELATED POLYGON: if (nodeS == nodeE) then begin pL = SOP.line[nL].Internal.LeftPoly; pR = SOP.line[nL].Internal.RightPoly; aIPL = SOP.poly[pL].POLYSTATS.Area; aIPR = SOP.poly[pR].POLYSTATS.Area; aIPv = SetMin(aIPL,aIPR); # TEST aIPv (AREA) AGAINST aIPMin: if (aIPv < aIPMin) then begin numEM = numEM + 1; delLlist[numEM] = nL; end end end # END OF PROCESS TO DEFINE & DELETE WEAK EDGES # ------------------------------------------------------------ printf("Done\n "); # PERFORM THE LINE-DELETION PROCESS (FOR SMALL ISLANDS): if (numEM > 0) then begin printf("DELETING %5d ISLAND-POLYGONS ......... ",numEM); if (numEM > 0) then begin VectorDeleteLines(SOP,delLlist,numEM); end printf("Done\n "); printf("(RE)BUILDING SOPs ...................... "); VectorValidate(SOP); printf("Done\n "); end if (numEM == 0) then begin printf(" No Island Polygons Were Deleted.\n "); end # ------------------------------------------------------------ if (optEP == 1) then begin # DELETE TABLE NAMED R_Props: db = OpenVectorPolyDatabase(SOP); table = DatabaseGetTableInfo(db,tname$); printf("DELETING R_Props DATABASE TABLE ........ "); err = TableDelete(table); printf("Done\n "); end # IF optEP == 2, THEN SUBJECT TABLE DOES NOT EXIST. # ------------------------------------------------------------ if (fThin >= 0.2) then begin # RUN LINE THINNING PROCESS: printf("THINNING VECTOR SOP LINES .............. "); VectorThinLines(SOP,"Douglas-Peucker",fThin); printf("Done\n "); VectorRemoveExcessNodes(SOP); printf("(RE)BUILDING SOPs ...................... "); VectorValidate(SOP); printf("Done\n "); end # ------------------------------------------------------------ # FINAL DELETION OF DANGLING LINES IN VECTOR SOP: lenLMax = 0; nvlins = SOP.$Info.NumLines; for nL=1 to nvlins begin lenL = SOP.line[nL].LINESTATS.Length; if (lenL > lenLMax) then lenLMax = lenL; end lenLMax = lenLMax + 1; printf("DELETING DANGLING LINES IN SOP ......... "); VectorDeleteDangleLines(SOP,lenLMax); printf("Done\n "); # ------------------------------------------------------------ # RE-SET Rin TO INPUT CONDITIONS & CLOSE IT: if (hnRin == 1) then begin SetNull(Rin,nvRin); DeleteHistogram(Rin); CreateHistogram(Rin,0); end CloseRaster(Rin); # ------------------------------------------------------------ # BUILDING FINAL SOPs: printf("(RE)BUILDING FINAL SOPs ................ "); VectorValidate(SOP); printf("Done\n\n"); # ------------------------------------------------------------ # MAKE REPORT OF VECTOR ELEMENTS IN FINAL SOP VECTOR OBJECT: nvlins = SOP.$Info.NumLines; nvpolys = SOP.$Info.NumPolys; printf("FINAL VECTOR SOPs & EDGE LINES:\n"); printf(" Polygons: %d",nvpolys); printf(" Lines: %d\n\n",nvlins); # ------------------------------------------------------------ # CLOSE VECTOR OBJECT SOP: CloseVector(SOP); # ------------------------------------------------------------ # DELETE TEMPORARY RASTER R: DeleteTempRaster(R); # ------------------------------------------------------------ printf("TO SAVE THE CONSOLE WINDOW TEXT AS A REPORT:\n"); printf(" 1. RIGHT-CLICK IN THE CONSOLE WINDOW.\n"); printf(" 2. SELECT THE Save As... OPTION.\n"); printf(" 3. NAVIGATE TO THE DESIRED LOCATION.\n"); printf(" 4. PROVIDE A REPORT NAME (or OVERWRITE).\n"); printf(" 5. CLICK OK.\n\n"); printf("*** TO CONTINUE, YOU MUST EXIT SML EDITOR ***"); # ------------------------------------------------------------ # DELETE DUMMY.rvc FILE: DeleteFile(fNameDum$);