Задача: "точка находится в N км СВ от заданной" - как?

Вопросы по нескольким пакетам сразу, или вопросы, которые непонятно к какой ГИС отнести
Ответить
Оборотень
Новоприбывший
Сообщения: 6
Зарегистрирован: 25 мар 2010, 14:18
Репутация: 0
Откуда: Томск
Контактная информация:

Задача: "точка находится в N км СВ от заданной" - как?

Сообщение Оборотень » 26 мар 2010, 18:54

В общем, при обработке рукописных и прочих данных часто встречается такая формулировка: "точка (место сбора, отлова, встречи и пр.) расположена в N км к востоку (любое направление) от г. (пос., с. и прочие реперы) Такого-то". Иными словами - даны репер, азимут и расстояние.
Требуется определить координаты (в любой проекции, но как правило, требуются угловые) этого места, имея координаты точки отсчёта (репера).
Как проще всего сделать это в ГИС? Использую ArcGIS 9.3 (лицензия ArcINFO).
Исходные данные - любые - шейпы, Feature Class типа Point.
Результат также возможен в любом виде - хоть новый объект класса Point, хоть рассчитанные координаты.
Есть ли готовый инструмент (в указанной ГИС)? Или требуется скрипт по вычислению координат на сфере - что в принципе мог бы сделать и сам, хотя тоже затрудняюсь - куда его писать?
Искал в Сети и на этом сайте, но (здесь) нашёл только задачу на построение по двум азимутам.
Буду благодарен как за прямой совет, так и за ссылку на статью.
Думаю, неплохо было бы создать такую статью (или ссылку) в FAQ сайта.
P.S. Репер - это не по высоте, а по координатам, как правильно обозвать - не знаю :(

KolesovDmitry
Гуру
Сообщения: 810
Зарегистрирован: 22 авг 2007, 14:58
Репутация: 123
Откуда: Казань

Re: Задача: "точка находится в N км СВ от заданной" - как?

Сообщение KolesovDmitry » 26 мар 2010, 20:41

Оборотень писал(а):"точка (место сбора, отлова, встречи и пр.) расположена в N км к востоку (любое направление) от г. (пос., с. и прочие реперы) Такого-то". Иными словами - даны репер, азимут и расстояние.
Требуется определить координаты (в любой проекции, но как правило, требуются угловые) этого места, имея координаты точки отсчёта (репера).
...
Результат также возможен в любом виде - хоть новый объект класса Point, хоть рассчитанные координаты.
Задача знакома, часто имел с ней дело (правда, работал только на плоскости). Как в arcGIS с этим делом не знаю, но общая идея проста: берет точки и производите ее трансформацию (возможность векторной трансформации дает многое ПО) по нужным параметрам (домножаете на нужный коэф, прибавляете нужный параметр и т.д.). Конкретная реализация зависит от того, что за возможности предоставляет ваше ПО.

Boris
Гуру
Сообщения: 4231
Зарегистрирован: 10 апр 2006, 22:34
Репутация: -344969098
Откуда: Париж

Re: Задача: "точка находится в N км СВ от заданной" - как?

Сообщение Boris » 27 мар 2010, 02:31

Эта задача имеет так много толкований. В вашем описании нет никакого азимута, кроме воображаемого. Поскольку не сказано, что принято направлением на север и в какой системе координат. Север может быть - астрономический (направление на Полярную звезду), географический - направление на север на конкретной карте или листе карты, магнитный - вообще нет ни на одной карте, за исключением военных или около военных.

Оборотень
Новоприбывший
Сообщения: 6
Зарегистрирован: 25 мар 2010, 14:18
Репутация: 0
Откуда: Томск
Контактная информация:

Re: Задача: "точка находится в N км СВ от заданной" - как?

Сообщение Оборотень » 31 мар 2010, 18:05

Хорошо, уточню.
1) Точность требуется почти минимальная (т.к. описания всеравно субъективные). Азимут будем считать - по меридиану, т.е. получается угол от географического Севера (правильно?). Причём в описаниях редко встречается угол, отличный от 90° или 45°. От СК, как я понимаю, будет зависеть только способ расчёта - Декартовы координаты (ну с поправкой на геоид) или полярные (тоже с какой-нить там поправкой :) ).
2) Интересует как раз _конкретный_ приём. Для _конкретного_ ПО (желательно - используемый мной, как уже упоминал, ArcGIS). Я конечно, мог бы вспомнить основы геометрии и считать непосредственно координаты в чём-нибудь типа Excel, но это больно уж неэффективно; кроме того, возможно имеется готовый инструмент.

KolesovDmitry
Гуру
Сообщения: 810
Зарегистрирован: 22 авг 2007, 14:58
Репутация: 123
Откуда: Казань

Re: Задача: "точка находится в N км СВ от заданной" - как?

Сообщение KolesovDmitry » 31 мар 2010, 18:49

Оборотень писал(а): Интересует как раз _конкретный_ приём. Для _конкретного_ ПО
Могу рассказать, как это можно сделать в GRASS, если конечно, это имеет смысл

Аватара пользователя
SS_Rebelious
Гуру
Сообщения: 1304
Зарегистрирован: 24 фев 2009, 16:51
Репутация: 99
Ваше звание: GIS pro-fan
Откуда: Lahti / Газ-ПУТИНбург
Контактная информация:

Re: Задача: "точка находится в N км СВ от заданной" - как?

Сообщение SS_Rebelious » 31 мар 2010, 19:08

KolesovDmitry писал(а):Могу рассказать, как это можно сделать в GRASS, если конечно, это имеет смысл
Да конечно имеет! Особенно если оформить в виде статьи!
Look for something long enough, and you will find it. Look for something without understanding, and it will find you...
"All paid jobs absorb and degrade the mind." Aristotle
If you take 1 step towards freedom it'll take 2 steps towards you!

Оборотень
Новоприбывший
Сообщения: 6
Зарегистрирован: 25 мар 2010, 14:18
Репутация: 0
Откуда: Томск
Контактная информация:

Re: Задача: "точка находится в N км СВ от заданной" - как?

Сообщение Оборотень » 01 апр 2010, 17:13

KolesovDmitry писал(а): Могу рассказать, как это можно сделать в GRASS, если конечно, это имеет смысл
Да, пожалуста расскажите. Тоже интересно, хотя с этим софтом не довелось иметь дела. Может, по аналогии получится.

pooperec
Интересующийся
Сообщения: 30
Зарегистрирован: 02 апр 2009, 11:12
Репутация: 0

Re: Задача: "точка находится в N км СВ от заданной" - как?

Сообщение pooperec » 01 апр 2010, 18:13

Вот рендерер. Рисует пеленг на заданный азимут для всех точек. Значение береться из Z координаты, для скорости. Отрисовка до 400 000 отметок / сек. Также есть возможность программно задавать символ точки пеленга и линии.

Недостаток - все пеленги рисуються с одной заданной длинной.

Разберётесь?

Код: Выделить всё

const
 CLASS_PelengRenderer : TGUID = '{52CDBCF0-1514-42E5-8726-EA2206339949}';

type 
  IPelengRenderer = interface(IUnknown)
    ['{D4332118-638C-4CDE-B169-A319B8AE8707}']
    procedure SetDistance(Distance: Integer); safecall;
    function Get_ParentSymbol: IUnknown; safecall;
    procedure Set_ParentSymbol(const Value: IUnknown); safecall;
    function Get_LineSym: IUnknown; safecall;
    procedure Set_LineSym(const Value: IUnknown); safecall;
    function Get_PointSym: IUnknown; safecall;
    procedure Set_PointSym(const Value: IUnknown); safecall;
    property ParentSymbol: IUnknown read Get_ParentSymbol write Set_ParentSymbol;
    property LineSym: IUnknown read Get_LineSym write Set_LineSym;
    property PointSym: IUnknown read Get_PointSym write Set_PointSym;
  end;

type
  TPelengRenderer = class(TTypedComObject, IPelengRenderer, IFeatureRenderer)
  public
   pExSet : IFeatureIDSet;
  Distance : integer;
  pSym  : ISymbol;
  pLineSym : ISymbol;
  pPointSym : iSymbol;
  protected
    function CanRender(const featClass: IFeatureClass;
      const Display: IDisplay): WordBool; safecall;
    function Get_RenderPhase(DrawPhase: esriDrawPhase): WordBool; safecall;
    function Get_SymbolByFeature(const Feature: IFeature): ISymbol; safecall;
    procedure _Set_ExclusionSet(const Param1: IFeatureIDSet); safecall;
    procedure Draw(const cursor: IFeatureCursor; DrawPhase: esriDrawPhase;
      const Display: IDisplay; const TrackCancel: ITrackCancel); safecall;
    procedure PrepareFilter(const fc: IFeatureClass;
      const queryFilter: IQueryFilter); safecall;
    procedure SetDistance(Distance: Integer); safecall;
    function Get_ParentSymbol: IUnknown; safecall;
    procedure Set_ParentSymbol(const Value: IUnknown); safecall;
    function Get_LineSym: IUnknown; safecall;
    procedure Set_LineSym(const Value: IUnknown); safecall;
    function Get_PointSym: IUnknown; safecall;
    procedure Set_PointSym(const Value: IUnknown); safecall;
    {Declare IPelengRednderer methods here}
  end;

implementation

uses ComServ;

function TPelengRenderer.CanRender(const featClass: IFeatureClass;
  const Display: IDisplay): WordBool;
begin
   Result:=false;
  if featClass.ShapeType=esriGeometryPoint then Result:=true;
end;

function TPelengRenderer.Get_RenderPhase(DrawPhase: esriDrawPhase): WordBool;
begin
   if (DrawPhase=esriDPGeography)OR(DrawPhase=esriDPSelection) then Result:=true
  else Result:=false;
end;

function TPelengRenderer.Get_SymbolByFeature(const Feature: IFeature): ISymbol;
begin

end;

procedure TPelengRenderer._Set_ExclusionSet(const Param1: IFeatureIDSet);
begin
  pExSet := Param1;
end;

procedure TPelengRenderer.Draw(const cursor: IFeatureCursor;
  DrawPhase: esriDrawPhase; const Display: IDisplay;
  const TrackCancel: ITrackCancel);
var
bContinue : boolean;
  pRow : IRow;
  o : integer;
  pPointF: IPoint;
  pPointT:IPoint;
  pExclude: Boolean;
  pOID: Integer;
  pLine : IPolyline;
    pF : IFeature;
  Angl : double;
begin
    if (Display=nil)OR(DrawPhase<>esriDPGeography) then exit;
    if (pLineSym=nil) or (pSym=nil) then exit;

    If trackCancel<>nil Then bContinue := trackCancel.Continue;

    pF:=cursor.NextFeature;

//    if pF<>nil then
//     o :=pF.Fields.FindField('AZIMUTH');
//    if o=0 then exit;

     while (pF<>nil) AND (bContinue) do Begin
          pPointT:=nil;
          pPointF:=nil;
          Angl:=0;
          pPointF:=pF.Shape as IPoint;
          Angl := pPointF.Z;
          if (round(Angl) div 360)>0  then Angl:=Angl - 360*(round(Angl) div 360)
          else Angl:=Angl - 360*(Angl);

          pExclude :=false;
          if pExSet<>nil then Begin
            pOID:=pF.OID;
            if pExSet.Contains[pOID] then pExclude:=true;
          End;

       if (pPointF.X>180)or(pPointF.X<-180) then pExclude:=true;
       if (pPointF.Y>90)or(pPointF.Y<-90) then pExclude:=true;

       if not(pExclude) then Begin
         try

         pPointT:=CoPoint.Create as IPoint;

         pPointT.Y:=pPointF.Y+20*cos(double(Angl)*pi/180);
         pPointT.X:=pPointF.X+20*sin(double(Angl)*pi/180);
//
         if (Angl>=0) then
         if NOT((pPointT.X>180)or(pPointT.X<-180)) then
         if NOT((pPointT.Y>90)or(pPointT.Y<-90)) then Begin
           pLine:=CoPolyline.Create as IPolyline;
           pLine.FromPoint:=pPointF;
           pLine.ToPoint:=pPointT;
           Display.SetSymbol(pLineSym);
           Display.DrawPolyline(pLine);
           Display.SetSymbol(pPointSym);
           Display.DrawPoint(pPointF);
         End else pPointT:=nil;
//         Display.SetSymbol(pSym);
//         Display.DrawPoint(ppointF);
         except on E:Exception do
          {$I-}
            ShowMessage(E.Message);
          {$I+}
         end;

       End;
        If trackCancel<>nil Then bContinue := trackCancel.Continue;
        pF:=cursor.NextFeature;

     End;
end;

procedure TPelengRenderer.PrepareFilter(const fc: IFeatureClass;
  const queryFilter: IQueryFilter);
begin
   if pExSet<>nil then
    if pExSet.Count>0 then Begin
      queryFilter.AddField(fc.OIDFieldName);
    End;
end;

procedure TPelengRenderer.SetDistance(Distance: Integer);
begin
  Distance:=Distance;
end;

function TPelengRenderer.Get_ParentSymbol: IUnknown;
begin
 Result:=pSym;
end;

procedure TPelengRenderer.Set_ParentSymbol(const Value: IUnknown);
begin
if supports(Value, ISymbol) then
  pSym:=Value as ISymbol;
end;

function TPelengRenderer.Get_LineSym: IUnknown;
begin
 Result:=pLineSym;
end;

procedure TPelengRenderer.Set_LineSym(const Value: IUnknown);
begin
 if supports(Value,Isymbol) then
   pLineSym:=Value as ISymbol;

end;

function TPelengRenderer.Get_PointSym: IUnknown;
begin
   Result:=pPointSym;
end;

procedure TPelengRenderer.Set_PointSym(const Value: IUnknown);
begin
   if supports(Value,Isymbol) then
   pPointSym:=Value as ISymbol;
end;

initialization
  TTypedComObjectFactory.Create(ComServer, TPelengRenderer, Class_PelengRenderer,
    ciMultiInstance, tmApartment);
end.

Ответить

Вернуться в «Общий - ПО»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 3 гостя