Линия Cell *m_firstCellPtr;
относится к типу Cell
, который явно не известен в этой точке.
Это очень вероятно, потому что книга просто показывает Stack
-части на этой странице, не упоминая, что вам придется объявить Cell
, например, включив что-то вроде #include "Cell.h"
Три способа выйти из этого:
#include "Cell.h"
, если ресурсы книги предоставят его class Cell;
до определения Stack
; class Cell *m_firstCellPtr;
Я не думаю, что необходимо использовать это решение. Случайным образом думая об этом несколько дней назад, я думаю, что, измеряя расстояние от отдельного момента местоположения квадратов сетки будут основаны на кругах, а не сетке одетой в форму. Еще дальше от 0,0 Вы - менее точное, которым это будет!
То, что я сделал, должно было иметь 2 дополнительных значения на моем классе PostalCode. Каждый раз, когда я обновляю Long/Lat на PostalCode, я вычисляю X, Y расстояние от Long 0, Lat 0.
public static class MathExtender
{
public static double GetDistanceBetweenPoints(double sourceLatitude, double sourceLongitude, double destLatitude, double destLongitude)
{
double theta = sourceLongitude - destLongitude;
double distance =
Math.Sin(DegToRad(sourceLatitude))
* Math.Sin(DegToRad(destLatitude))
+ Math.Cos(DegToRad(sourceLatitude))
* Math.Cos(DegToRad(destLatitude))
* Math.Cos(DegToRad(theta));
distance = Math.Acos(distance);
distance = RadToDeg(distance);
distance = distance * 60 * 1.1515;
return (distance);
}
public static double DegToRad(double degrees)
{
return (degrees * Math.PI / 180.0);
}
public static double RadToDeg(double radians)
{
return (radians / Math.PI * 180.0);
}
}
Затем я обновляю свой класс как так:
private void CalculateGridReference()
{
GridReferenceX = MathExtender.GetDistanceBetweenPoints(0, 0, 0, Longitude);
GridReferenceY = MathExtender.GetDistanceBetweenPoints(0, 0, Latitude, 0);
}
Таким образом, теперь у меня есть x, y расстояние сетки (в милях) из ссылки сетки 0,0 для каждой строки в моем DB. Если бы я хочу найти все места с 5 милями long/lat, я сначала получил бы эти X, Y ссылка сетки (скажите 25,75), затем, я искал бы 20.. 30, 70.. 80 в DB и дальнейшем фильтре результаты в использовании памяти
MathExtensder.GetDistanceBetweenPoints(candidate.Lat, candidate.Long, search.Lat, search.Long) < TheRadiusOfInterest
В части DB крайний быстрый, и работы части в оперативной памяти над меньшим набором для создания этого крайним точный.
Использовать R-Trees
.
В Oracle, с помощью Пространственной Oracle, можно создать индекс:
CREATE INDEX ix_spatial ON spatial_table (locations) INDEXTYPE IS MDSYS.SPATIAL_INDEX;
это создаст R-Tree
для Вас и поиска по нему.
Можно использовать любого Earth Model
Вам нравится: WGS84
, PZ-90
и т.д.
Используйте некоторое дерево поиска для пространственных данных, например, дерево квадрантов. На большее количество таких структур данных ссылаются под, "См. также".
Вы могли, возможно, предоставить образец своего существующего дорогого запроса?
Если Вы делаете надлежащее большое круговое вычисление на основе взятия синуса () и косинус () контрольной точки и других точек данных, то очень существенная оптимизация могла быть сделана путем фактического хранения тех значений sin/cos в базе данных в дополнение к значениям lat/long.
С другой стороны, просто используйте свою базу данных для извлечения прямоугольника диапазонов lat/long, которые соответствуют и только впоследствии отфильтровывают тех, которые являются вне истинного кругового радиуса.
Но действительно примите во внимание, что один градус долготы является несколько более коротким расстоянием в высоких широтах, чем на экватор. Должно быть легко выяснить правильное соотношение сторон для того прямоугольника, все же. У Вас также были бы ошибки, если бы необходимо рассмотреть области очень близко к полюсам, поскольку rectanglar выбор не справился бы с кругом, который перекрыл полюс.
Этот UDF (SQL Server) получит Вас расстояние между двумя точками lat/lon:
CREATE FUNCTION [dbo].[zipDistance] (
@Lat1 decimal(11, 6),
@Lon1 decimal(11, 6),
@Lat2 decimal(11, 6),
@Lon2 decimal(11, 6)
)
RETURNS
decimal(11, 6) AS
BEGIN
IF @Lat1 = @Lat2 AND @Lon1 = @Lon2
RETURN 0 /* same lat/long points, 0 distance = */
DECLARE @x decimal(18,13)
SET @x = 0.0
/* degrees -> radians */
SET @Lat1 = @Lat1 * PI() / 180
SET @Lon1 = @Lon1 * PI() / 180
SET @Lat2 = @Lat2 * PI() / 180
SET @Lon2 = @Lon2 * PI() / 180
/* accurate to +/- 30 feet */
SET @x = Sin(@Lat1) * Sin(@Lat2) + Cos(@Lat1) * Cos(@Lat2) * Cos(@Lon2 - @Lon1)
IF 1 = @x
RETURN 0
DECLARE @EarthRad decimal(5,1)
SET @EarthRad = 3963.1
RETURN @EarthRadius * (-1 * ATAN(@x / SQRT(1 - @x * @x)) + PI() / 2)
END
И, очевидно, можно использовать это в отдельном запросе, таком как:
SELECT * FROM table WHERE [dbo].[zipDistance] < 25.0