 |
www.integro.ru ЦСИ ИНТЕГРО
|
Предыдущая тема :: Следующая тема |
Автор |
Сообщение |
Codegen
Зарегистрирован: 26.03.2006 Сообщения: 14 Откуда: Екатеринбург
|
Добавлено: Пт 31 Мар 2006 16:11 Заголовок сообщения: Файл с изображением карты в формате EMF |
|
|
Пытаюсь получить изображение карты командой
Код: |
procedure GetEMF(Ingeo: IIngeoApplication; aResX, aResY, aSizeX, aSizeY: Longint; CenterX, CenterY, ZoomScale, XAngle: double; YMirror: boolean);
begin
Ingeo.ActiveProjectView.MakeImageFile(aResX, aResY, aSizeX, aSizeY, CenterX, CenterY, ZoomScale, XAngle, YMirror, clWhite, 'C:\123.emf');
end;
|
Получаю следующую ошибку:
Ошибка имени растрового файла: некорректное расширение файла.
Если ставить расширение bmp, jpg, gif то изображение создается. Это не подходит, как получить emf? В хелпе указано что это можно сделать. |
|
Вернуться к началу |
|
 |
Codegen
Зарегистрирован: 26.03.2006 Сообщения: 14 Откуда: Екатеринбург
|
Добавлено: Сб 01 Апр 2006 22:55 Заголовок сообщения: |
|
|
Нашел в чем ошибка..
Имя файла не должно начинаться на цифру, т.е. 123.emf - так нельзя, qwerty123.emf - так сработает.
Привожу функцию, которая возвращает копию экрана Ингео, она некорректно работает для EMF. Код полностью рабочий. Надеюсь этот баг будет исправлен как можно быстрее. Он тормозит мою разработку!
Код: | function GetPicture(Ingeo: IIngeoApplication; zAngle: double): IInImage;
var
IngeoDb: IIngeoDb;
theImage: IInImage;
// копируем вариантный массив в поток
function VariantArrayToStream(VarArray: OleVariant): TMemoryStream;
var
pLocked: Pointer;
begin
Result:= TMemoryStream.Create;
if VarIsEmpty(VarArray) or VarIsNull(VarArray) then Exit;
Result.Size := VarArrayHighBound(VarArray, 1) - VarArrayLowBound(VarArray, 1) + 1;
pLocked := VarArrayLock(VarArray);
try
Result.Write(pLocked^, Result.Size);
finally
VarArrayUnlock(VarArray);
Result.Position := 0;
end;
end;
procedure PaintObject(anID: String);
var
IngeoMapObject: IIngeoMapObject;
begin
IngeoMapObject := IngeoDb.MapObjects.GetObject(anID);
if not assigned(IngeoMapObject) then exit;
IngeoMapObject.Paint(theImage.Surface);
end;
function ZoomScaleInRange(aZoomScale, aMinScale, aMaxScale: Double): Boolean;
begin
Result :=
(aZoomScale = 0) or
(((aMinScale = 0) or
((aMinScale > 0) and (aZoomScale <= aMinScale)) or
((aMinScale < 0) and (aZoomScale < -aMinScale)))
and
((aMaxScale = 0) or
((aMaxScale > 0) and (aZoomScale >= aMaxScale)) or
((aMaxScale < 0) and (aZoomScale > -aMaxScale))))
end;
function LayerHaveVisibleSyles(aZoomScale: Double; const aLayer: IIngeoLayer): Boolean;
var
aStyle: IIngeoStyle;
aPainter: IIngeoPainter;
i, j: Integer;
begin
Result := True;
for i := 0 to aLayer.Styles.Count - 1 do begin
aStyle := aLayer.Styles[i];
for j := 0 to aStyle.Painters.Count - 1 do begin
aPainter := aStyle.Painters[j];
if ZoomScaleInRange(aZoomScale, aPainter.VisibleMin, aPainter.VisibleMax) then
Exit;
end;
end;
Result := False;
end;
var
IngeoProjectView: IIngeoProjectView;
IngeoMapView: IIngeoMapView;
IngeoLayerView: IIngeoLayerView;
IngeoMapObjects: IIngeoMapObjects;
IngeoMapObjectsQuery: IIngeoMapObjectsQuery;
aZoomScale, xx1, yy1, xx2, yy2, x1, y1, x2, y2: double;
i, j: integer;
zStream: TMemoryStream;
IngeoMapWindow: IIngeoMapWindow;
ProjectionNavigator: IIngeoMatrixProjectionNavigator;
begin
// создаем экземпляр картинки
theImage := Ingeo.CreateObject(inocImage, EmptyParam) as IInImage;
// устанавливаем разрешение и размеры картинки
theImage.ResolutionX := 96;
theImage.ResolutionY := 96;
with Ingeo.MainWindow.MapWindow.Surface do begin
theImage.Width := DeviceRight - DeviceLeft;
theImage.Height := DeviceBottom - DeviceTop;
end;
IngeoMapWindow := Ingeo.MainWindow.MapWindow;
ProjectionNavigator := IngeoMapWindow.Navigator as IIngeoMatrixProjectionNavigator;
// синхронизируем положение картинки с окном ингео
with ProjectionNavigator do theImage.Surface.Navigator.Navigate(CenterX, CenterY, ZoomScale);
IngeoDb := Ingeo.ActiveDb;
IngeoProjectView := Ingeo.ActiveProjectView;
IngeoMapObjects := Ingeo.ActiveDb.MapObjects;
// получаем координаты левой верхней и правой нижней точки карты в ингео
with theImage.Surface do begin
PointDeviceToWorld(DeviceLeft, DeviceTop, x1, y1);
PointDeviceToWorld(DeviceRight, DeviceBottom, x2, y2);
aZoomScale := Projection.ZoomScale;
ProjectionNavigator := Navigator as IIngeoMatrixProjectionNavigator;
ProjectionNavigator.YMirror := IngeoMapWindow.Surface.Projection.YMirror;
// ставим какой-то свой угол поворота карты,
// карта отрисовывается с нужным углом, но потом ни как не прочитать
// реальный угол!!
ProjectionNavigator.XAngle := zAngle;
end;
// если так не сделать, то QueryByRect не работает
xx1 := Min(x1, x2); yy1 := Min(y1, y2);
xx2 := Max(x1, x2); yy2 := Max(y1, y2);
// проходим по всем картам/слоям, видимые объекты отрисовываем на theImage
for i := IngeoProjectView.MapViews.Count - 1 downto 0 do begin
IngeoMapView := IngeoProjectView.MapViews[i];
if not IngeoMapView.Visible or not ZoomScaleInRange(aZoomScale, IngeoMapView.Map.VisibleMin, IngeoMapView.Map.VisibleMax) then Continue;
for j := IngeoMapView.LayerViews.Count - 1 downto 0 do begin
IngeoLayerView := IngeoMapView.LayerViews[j];
if not IngeoMapView.Visible or not ZoomScaleInRange(aZoomScale, IngeoLayerView.Layer.VisibleMin, IngeoLayerView.Layer.VisibleMax) or
not LayerHaveVisibleSyles(aZoomScale, IngeoLayerView.Layer) then Continue;
IngeoMapObjectsQuery := IngeoMapObjects.QueryByRect(IngeoLayerView.Layer.ID, xx1, yy1, xx2, yy2, false);
while not IngeoMapObjectsQuery.EOF do begin
PaintObject(IngeoMapObjectsQuery.ObjectID);
IngeoMapObjectsQuery.MoveNext;
end;
end;
end;
zStream := VariantArrayToStream(theImage.Data[inidBMP]);
zStream.SaveToFile('C:\bmp.bmp');
theImage.SaveToFile('C:\~bmp.bmp');
zStream.Clear;
zStream := VariantArrayToStream(theImage.Data[inidJPEG]);
zStream.SaveToFile('C:\jpeg.jpeg');
theImage.SaveToFile('C:\~jpeg.jpeg');
zStream.Clear;
zStream := VariantArrayToStream(theImage.Data[inidGIF]);
zStream.SaveToFile('C:\gif.gif');
theImage.SaveToFile('C:\~gif.gif');
zStream.Clear;
try
zStream := VariantArrayToStream(theImage.Data[inidEMF]);
// ФАЙЛ СОЗДАЕТСЯ, НО ОН ПУСТОЙ
zStream.SaveToFile('C:\emf.emf');
// ОШИБКА ИМЕНИ РАСТРОВОГО ФАЙЛА: НЕКОРРЕКТНОЕ РАСШИРЕНИЕ ФАЙЛА
theImage.SaveToFile('C:\~emf.emf');
finally
zStream.Clear;
zStream.Free;
result := theImage;
end;
end;
|
P.S.
Нашел еще один очень досадный баг.. Image который возвращает приведенная функция не корректно возвращает XAngle:
Код: | procedure TReportForm.Button1Click(Sender: TObject);
var
theImage: IInImage;
angle1, angle2: double;
begin
try
// угол поворота карты ставим ноль
theImage := GetPicture(Ingeo, 0);
finally
angle1 := OleVariant(theImage.Surface.Navigator).XAngle;
angle2 := (theImage.Surface.Navigator as IIngeoMatrixProjectionNavigator).XAngle;
// угол поворота всегда Pi/2!!
MessageBox(Handle, PChar(FloatToStr(angle1)), 'OleVariant(theImage.Surface.Navigator).XAngle', MB_APPLMODAL);
MessageBox(Handle, PChar(FloatToStr(angle2)), '(theImage.Surface.Navigator as IIngeoMatrixProjectionNavigator).XAngle', MB_APPLMODAL);
theImage := nil;
end;
end;
|
|
|
Вернуться к началу |
|
 |
Кузнецов Андрей
Зарегистрирован: 22.04.2005 Сообщения: 28 Откуда: Магнитогорск
|
Добавлено: Вт 04 Апр 2006 12:08 Заголовок сообщения: |
|
|
Можно немного сократить код используя метод PaintXml.
Вот примерчики на vbs:
Код: |
Sub PaintLayerByID (aDB, aSurface, aLayerID)
aDB.PaintXml aSurface, "<paint><layer oid='" & aLayerID & "' /></paint>"
end Sub
Sub PaintMapByID (aDB, aSurface, aMapID)
aDB.PaintXml aSurface, "<paint><map oid='" & aMapID & "' /></paint>"
end Sub
Sub PaintProjectByID (aDB, aSurface, aProjectID)
aDB.PaintXml aSurface, "<paint><project oid='" & aProjectID & "' /></paint>"
end Sub
|
|
|
Вернуться к началу |
|
 |
Рустам Тукаев Администратор сайта
Зарегистрирован: 14.02.2005 Сообщения: 30 Откуда: ИНТЕГРО
|
Добавлено: Вт 04 Апр 2006 15:43 Заголовок сообщения: Файл с изображением карты в формате EMF |
|
|
Codegen писал(а): | IInImage .. |
Во-первых, IInImage не умеет создавать emf файлы
Во-вторых, если нужно создать файл с изображением карты, лучше использовать метод MakeImageFile объекта типа IIngeoProjectView
вот примерчик на vbs:
Код: |
sub MakeImageFile(aFileName, aWorldX1, aWorldY1, aWorldX2, aWorldY, aZoomScale, aResolution, aForeColor)
dim aProjection
dim aSizeX, aSizeY
dim aCenterX, aCenterY, anAngle
dim aProjectView, aSurface
if aZoomScale <> 0 then
aZoomScale = 1/aZoomScale
end if
set aSurface = Application.MainWindow.MapWindow.Surface
set aProjection = aSurface.Projection
set aProjectView = Application.ActiveProjectView
anAngle = Application.MainWindow.MapWindow.Navigator.XAngle*180/pi
aSizeX = CInt(Abs(aWorldX1 - aWorldX2)*(aResolution / 0.0254)*aZoomScale)
aSizeY = CInt(Abs(aWorldY2 - aWorldY1)*(aResolution / 0.0254)* aZoomScale)
aCenterX = (aWorldX1 + aWorldX2)/2
aCenterY = (aWorldY2 + aWorldY1)/2
call aProjectView.MakeImageFile(aResolution, aResolution, aSizeX, aSizeY, aCenterX, aCenterY, _
aZoomScale, anAngle, aProjection.YMirror, aForeColor, _
aFileName)
end sub
sub MakeMapWindowImageFile(aFileName, aZoomScale, aResolution, aForeColor)
dim aWorldX1, aWorldY1, aWorldX2, aWorldY2
with Application.MainWindow.MapWindow.Surface
aWorldX1 = .PaperX1
aWorldY1 = .PaperY1
aWorldX2 = .PaperX2
aWorldY2 = .PaperY2
call .Projection.sUnProjectBounds(aWorldX1, aWorldY1, aWorldX2, aWorldY2, aWorldX1, aWorldY1, aWorldX2, aWorldY2)
end with
call MakeImageFile(aFileName, aWorldX1, aWorldY1, aWorldX2, aWorldY2, aZoomScale, aResolution, aForeColor)
end sub
MakeMapWindowImageFile "C:\1.emf", 500, 100, vbWhite
|
В-третьих, если вам нужно вставить изображение карты в Word, например, то нет необходимости создавать файл, можно сделать так:
Код: |
sub MakeImage(X1, Y1, X2, Y2, MapScale)
dim LayoutWindow, Map
set LayoutWindow = OpenWindow("LayoutWindow", Null)
LayoutWindow.Visible = False
set Map = LayoutWindow.Figures.Add(inftMap)
Map.CenterX = (X1 + X2) / 2
Map.CenterY = (Y1 + Y2) / 2
Map.ZoomScale = 1/MapScale
Map.Width = ((Y2 - Y1) + 10)* Map.ZoomScale
Map.Height = ((X2 - X1) + 10)* Map.ZoomScale
LayoutWindow.Actions("ActionsEditSelectAll").Execute
LayoutWindow.Actions("ActionsEditCopy").Execute
LayoutWindow.Close
end sub
sub MakeDocument
dim Word, Doc, Range
Set Word = CreateObject("Word.Application")
Word.Visible = True
Set Doc = Word.Documents.Add("c:\template.dot")
Doc.Bookmarks("Map").Range.Paste
Doc.Range.InlineShapes(1).Width = PictureWidthInMM
Doc.Range.InlineShapes(1).ScaleHeight = Doc.Range.InlineShapes(1).ScaleWidth
end sub
|
В-четвертых, действительно Surface.Navigator не правильно возвращает угол, эта ошибка будет исправлена, но сейчас можно использовать MapWindow.Navigator |
|
Вернуться к началу |
|
 |
|
|
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете голосовать в опросах Вы не можете добавлять приложения в этом форуме Вы можете скачивать файлы в этом форуме
|
|