/** * Fill 16 values of HGT near required coordinates * can use HGTreaders near the current one */ private bool FillArray(HGTReader rdr, int row, int col, int xLeft, int yBottom) { int res = rdr.GetRes(); int minX = 0; int minY = 0; int maxX = 3; int maxY = 3; bool inside = true; // check borders if (xLeft == 0) { if (col <= 0) { return(false); } minX = 1; inside = false; } else if (xLeft == res - 1) { if (col + 1 >= readers[0].Length) { return(false); } maxX = 2; inside = false; } if (yBottom == 0) { if (row <= 0) { return(false); } minY = 1; inside = false; } else if (yBottom == res - 1) { if (row + 1 >= readers.Length) { return(false); } maxY = 2; inside = false; } // fill data from current reader short h; for (int x = minX; x <= maxX; x++) { for (int y = minY; y <= maxY; y++) { h = rdr.Ele(xLeft + x - 1, yBottom + y - 1); if (h == HGTReader.UNDEF) { return(false); } eleArray[x][y] = h; maxhöhe = Math.Max(maxhöhe, h); minhöhe = Math.Min(minhöhe, h); } } if (inside) // no need to check borders again { return(true); } // fill data from adjacent readers, down and up if (xLeft > 0 && xLeft < res - 1) { if (yBottom == 0) { // bottom edge HGTReader rdrBB = PrepReader(res, row - 1, col); if (rdrBB == null) { return(false); } for (int x = 0; x <= 3; x++) { h = rdrBB.Ele(xLeft + x - 1, res - 1); if (h == HGTReader.UNDEF) { return(false); } eleArray[x][0] = h; } } else if (yBottom == res - 1) { // top edge HGTReader rdrTT = PrepReader(res, row + 1, col); if (rdrTT == null) { return(false); } for (int x = 0; x <= 3; x++) { h = rdrTT.Ele(xLeft + x - 1, 1); if (h == HGTReader.UNDEF) { return(false); } eleArray[x][3] = h; } } } // fill data from adjacent readers, left and right if (yBottom > 0 && yBottom < res - 1) { if (xLeft == 0) { // left edgge HGTReader rdrLL = PrepReader(res, row, col - 1); if (rdrLL == null) { return(false); } for (int y = 0; y <= 3; y++) { h = rdrLL.Ele(res - 1, yBottom + y - 1); if (h == HGTReader.UNDEF) { return(false); } eleArray[0][y] = h; } } else if (xLeft == res - 1) { // right edge HGTReader rdrRR = PrepReader(res, row, col + 1); if (rdrRR == null) { return(false); } for (int y = 0; y <= 3; y++) { h = rdrRR.Ele(1, yBottom + y - 1); if (h == HGTReader.UNDEF) { return(false); } eleArray[3][y] = h; } } } // fill data from adjacent readers, corners if (xLeft == 0) { if (yBottom == 0) { // left bottom corner HGTReader rdrLL = PrepReader(res, row, col - 1); if (rdrLL == null) { return(false); } for (int y = 1; y <= 3; y++) { h = rdrLL.Ele(res - 1, yBottom + y - 1); if (h == HGTReader.UNDEF) { return(false); } eleArray[0][y] = h; } HGTReader rdrBB = PrepReader(res, row - 1, col); if (rdrBB == null) { return(false); } for (int x = 1; x <= 3; x++) { h = rdrBB.Ele(xLeft + x - 1, res - 1); if (h == HGTReader.UNDEF) { return(false); } eleArray[x][0] = h; } HGTReader rdrLB = PrepReader(res, row - 1, col - 1); if (rdrLB == null) { return(false); } h = rdrLB.Ele(res - 1, res - 1); if (h == HGTReader.UNDEF) { return(false); } eleArray[0][0] = h; } else if (yBottom == res - 1) { // left top corner HGTReader rdrLL = PrepReader(res, row, col - 1); if (rdrLL == null) { return(false); } for (int y = 0; y <= 2; y++) { h = rdrLL.Ele(res - 1, yBottom + y - 1); if (h == HGTReader.UNDEF) { return(false); } eleArray[0][y] = h; } HGTReader rdrTT = PrepReader(res, row + 1, col); if (rdrTT == null) { return(false); } for (int x = 1; x <= 3; x++) { h = rdrTT.Ele(xLeft + x - 1, 1); if (h == HGTReader.UNDEF) { return(false); } eleArray[x][3] = h; } HGTReader rdrLT = PrepReader(res, row + 1, col - 1); if (rdrLT == null) { return(false); } h = rdrLT.Ele(res - 1, 1); if (h == HGTReader.UNDEF) { return(false); } eleArray[0][3] = h; } } else if (xLeft == res - 1) { if (yBottom == 0) { // right bottom corner HGTReader rdrRR = PrepReader(res, row, col + 1); if (rdrRR == null) { return(false); } for (int y = 1; y <= 3; y++) { h = rdrRR.Ele(1, yBottom + y - 1); if (h == HGTReader.UNDEF) { return(false); } eleArray[3][y] = h; } HGTReader rdrBB = PrepReader(res, row - 1, col); if (rdrBB == null) { return(false); } for (int x = 0; x <= 2; x++) { h = rdrBB.Ele(xLeft + x - 1, res - 1); if (h == HGTReader.UNDEF) { return(false); } eleArray[x][0] = h; } HGTReader rdrRB = PrepReader(res, row - 1, col + 1); if (rdrRB == null) { return(false); } h = rdrRB.Ele(1, res - 1); if (h == HGTReader.UNDEF) { return(false); } eleArray[3][0] = h; } else if (yBottom == res - 1) { // right top corner HGTReader rdrRR = PrepReader(res, row, col + 1); if (rdrRR == null) { return(false); } for (int y = 0; y <= 2; y++) { h = rdrRR.Ele(1, yBottom + y - 1); if (h == HGTReader.UNDEF) { return(false); } eleArray[3][y] = h; } HGTReader rdrTT = PrepReader(res, row + 1, col); if (rdrTT == null) { return(false); } for (int x = 0; x <= 2; x++) { h = rdrTT.Ele(xLeft + x - 1, 1); if (h == HGTReader.UNDEF) { return(false); } eleArray[x][3] = h; } HGTReader rdrRT = PrepReader(res, row + 1, col + 1); if (rdrRT == null) { return(false); } h = rdrRT.Ele(1, 1); if (h == HGTReader.UNDEF) { return(false); } eleArray[3][3] = h; } } // all 16 values present return(true); }
protected double GetElevation(int lat32, int lon32) { int row = (int)((lat32 - minLat32) * FACTOR); int col = (int)((lon32 - minLon32) * FACTOR); HGTReader rdr = readers[row][col]; if (rdr == null) { // no reader : ocean or missing file return(outsidePolygonHeight); } int res = rdr.GetRes(); rdr.PrepRead(); if (res <= 0) { return(0); // assumed to be an area in the ocean } lastRow = row; double scale = res * FACTOR; double y1 = (lat32 - minLat32) * scale - row * res; double x1 = (lon32 - minLon32) * scale - col * res; int xLeft = (int)x1; int yBottom = (int)y1; double qx = x1 - xLeft; double qy = y1 - yBottom; //statPoints++; if (useComplexInterpolation) { // bicubic (Catmull-Rom) interpolation with 16 points bool filled = FillArray(rdr, row, col, xLeft, yBottom); if (filled) { h = BicubicInterpolation(eleArray, qx, qy); //statBicubic++; } } if (h == HGTReader.UNDEF || !useComplexInterpolation) { // use bilinear interpolation if bicubic not available int xRight = xLeft + 1; int yTop = yBottom + 1; int hLT = rdr.Ele(xLeft, yTop); maxhöhe = Math.Max(maxhöhe, hLT); minhöhe = Math.Min(minhöhe, hLT); int hRT = rdr.Ele(xRight, yTop); maxhöhe = Math.Max(maxhöhe, hRT); minhöhe = Math.Min(minhöhe, hRT); int hLB = rdr.Ele(xLeft, yBottom); maxhöhe = Math.Max(maxhöhe, hLB); minhöhe = Math.Min(minhöhe, hLB); int hRB = rdr.Ele(xRight, yBottom); maxhöhe = Math.Max(maxhöhe, hRB); minhöhe = Math.Min(minhöhe, hRB); h = InterpolatedHeight(qx, qy, hLT, hRT, hRB, hLB); //statBilinear++; //if (h == HGTReader.UNDEF) statVoid++; } //if (h == HGTReader.UNDEF && log.isLoggable(Level.WARNING)) //{ // double lon = lon32 * FACTOR; // double lat = lat32 * FACTOR; // Coord c = new Coord(lat, lon); // log.warn("height interpolation returns void at", c.toDegreeString()); //} return(h); }