Проблема такова: В прикрепленном файле находятся файлы KRD-карты районов. Каждый из них содержит название района, координаты точек, макс. и мин. значения "х" и "у". Помогите вывести на экран хотя бы одну карту
type TForm1 = class(TForm) Image1: TImage; Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end;
var Form1: TForm1; x,y,h:real; I1,I2,J1,J2:integer; x1,x2,y1,y2:real; implementation
{$R *.dfm} {------------------------------------------------------------------------------} function II(x:real):Integer; begin II:=I1 + Trunc ((x-x1)*(I2-I1)/(x2-x1)) end; {------------------------------------------------------------------------------} function JJ(y:real):Integer; begin JJ:=J1 + Trunc ((y-y1)*(J2-J1)/(y2-y1)) end; {------------------------------------------------------------------------------} procedure TForm1.Button1Click(Sender: TObject); begin with Image1
Смотрю по коду, вроде должно работать, но все равно карту не рисует из файла: 1.Название района 2.Название райцентра 3.Координаты 4.,5.Макс по Х и мин по Х, соотевтсвенно макс по у и мин по у... Остальные просто координаты! В качестве примера взял один файл с название "район1"
Код
var Form1: TForm1; x1,y1,x2,y2,h:real; x,y,col:integer; I1,J1,I2,J2,n,j,k:integer; s1,s2:string; f:TextFile; implementation
{$R *.dfm} {------------------------------------------------------------------------------} function II(x:real):integer; begin II:=I1+Trunc((x-x1)*(I2-I1)/(x2-x1)) end; {------------------------------------------------------------------------------} function JJ(x:real):integer; begin JJ:=J1+Trunc((y-y1)*(J2-J1)/(y2-y1)) end; {------------------------------------------------------------------------------} procedure DrawGraphic; begin reset(f); k:=0; with Form1.Image1,Form1.Image1.Canvas do begin x:=1413;y:=1294; MoveTo(II(x),JJ(-y)); while not eof(f) do begin k:=k+1; while not eoln(f) do begin Rectangle(0,0,Width,Height); if (k=1)or(k=2) then
read(f,s1)
else if k=4 then read(f,n) else if k=7 then read(f,col) else begin read(f,x,y); LineTo(II(x),JJ(-y)) end end; readln(f) end; close(f); end; end; {------------------------------------------------------------------------------} procedure TForm1.FormCreate(Sender: TObject); begin AssignFile(f, 'D:\Documents and Settings\Administrator\My Documents\Delfi_files\Map\RAION1.KRD');
Что значит вывести? Что должно получиться на экране? Название района и куча точек?
Автор: }0pa 19.11.2006 21:24
Да, куча точек - карта района с его названием и названиеи райцентра!
Автор: hiv 21.11.2006 15:12
Что означает 7 в 7-ой строке файла данных о районе?
Автор: hiv 21.11.2006 16:19
Вроде что-то получилось Region.rar ( 6.81 килобайт )
Кол-во скачиваний: 440
Вот как выглядит: ЗЫ: Если хочешь несколько районов, то используй массив из TRegion. Но не забудь, что пересчитывать Delta (относительное смещение координат карты и формы на экране) придется для каждого региона по другому.
Автор: }0pa 22.11.2006 5:50
Большой респект. Нашел свои ошибки!!!Спасибо!
Автор: }0pa 22.11.2006 22:29
Цитата
Если хочешь несколько районов, то используй массив из TRegion
Не мог ты написать пример хотя бы для 2 карт.
Автор: }0pa 23.11.2006 6:30
Код
Canvas.Ellipse(Region.CenterX-Region.Delta.X-th div 2 - 1,Region.CenterY-Region.Delta.Y-th div 2 - 1,Region.CenterX-Region.Delta.X+ th div 2,Region.CenterY-Region.Delta.Y+ th div 2);
Помогите разобраться в строчке
Понятно,что это эллипс, но каким же образом мы выбираем эти коордниты?
Автор: hiv 23.11.2006 13:14
Цитата(}0pa @ 23.11.2006 2:30)
Понятно,что это эллипс, но каким же образом мы выбираем эти коордниты?
(Region.CenterX,Region.CenterY) - центр окружности th - ее диаметр (берется размером с высоту шрифта которым подписывать будем) th div 2 - ее радиус (деление нацело) Region.Delta - смещение координат по X и Y Геометрию то помнишь?
Вместо Region :TRegion; пишешь Region :array of TRegion; Перед добавлением региона не забывай увеличить размер динамического массива: setlength(Region,length(Region)+1);
Автор: }0pa 23.11.2006 16:37
Цитата(hiv @ 21.11.2006 12:19)
Но не забудь, что пересчитывать Delta (относительное смещение координат карты и формы на экране) придется для каждого региона по другому.
1.Наверное, придется заносить сещение в массив? 2.К тому же, нужно нарисовать карту региона,т.е.этот район не обязательно должен находиться в левом углу формы? 3.А нельзя ли не изменять в файле имя района и райцентра, вывести на экран при считывания из файла, эти имена в норм. "русской форме"?
Автор: hiv 23.11.2006 20:05
Цитата(}0pa @ 23.11.2006 12:37)
1.Наверное, придется заносить сещение в массив? 2.К тому же, нужно нарисовать карту региона,т.е.этот район не обязательно должен находиться в левом углу формы? 3.А нельзя ли не изменять в файле имя района и райцентра, вывести на экран при считывания из файла, эти имена в норм. "русской форме"?
1. Смещение находится в объекте, поэтому заносить его в массив не надо, т.к. сами объекты уже в массиве. Возможно нужно убрать смещение из регионов, если они у тебя относительно друг друга правильно расположены, и ввести общее смещение. Его вычислять как минимальное значение из Region[i].Rect.Left по X и минимальное значение из Region[i].Rect.Top по Y. 2. см. ответ на вопрос 1. 3. Можно, тогда ищи функцию перекодировки cp866 в кодировку cp1251. На форуме точно есть. Начни с FAQ
Автор: }0pa 26.11.2006 21:57
Масштаб не получается реализовать, т.е. на форме вся карта не умещаетя...Смещение для каждого района убрал и поставил для всей карты
Автор: }0pa 27.11.2006 4:07
Вот этот проэкт. Вся карта не помещается на форму. Помогите организовать масштаб
Вот этот проэкт. Вся карта не помещается на форму. Помогите организовать масштаб
Добавил масштаб (чего нет проще - подели итоговые координаты на масштаб и все!) Исправил кучу нелепостей особенно с OnPaint (он должен быть связан с формой) и поиском файлов. region.rar ( 24.88 килобайт )
Кол-во скачиваний: 414
Автор: }0pa 27.11.2006 17:54
С маштабом я потом сам догадался, вспомнив про сжатие и растяжение. А вот, конечно, за поиск очередного файла с раширение КРД и за оптимизацию событийных процедур огромное спасибо! Р.С. Помнится, вы спрашивали про 7 строчку в файле: это есть не что иное, как цвет района Region.Cvet - содержит цвет, но при его подстановки в
Происходит неурядица. И вот насчет кодировки у меня ничего в голову не лезет
Автор: hiv 27.11.2006 18:16
Посмотри описание объекта TColor; Из него можно создать палитру (массив цветов), номер в которой и будет твоим номером цвета.
Автор: }0pa 27.11.2006 18:41
Sorry, сам разобрался...
Код
Function MyColor(c:integer):TColor; begin case c of 0:MyColor:=clBlack; 1:MyColor:=clBlue; 2:MyColor:=clGreen; 3:MyColor:=clLime; 4:MyColor:=clRed; 5:MyColor:=clSilver; 6:MyColor:=clMaroon; 7:MyColor:=clOlive; 8:MyColor:=clNavy; 9:MyColor:=clAqua; 10:MyColor:=clYellow; 11:MyColor:=clPurple; 12:MyColor:=clTeal; 13:MyColor:=clWhite; end; end;
Может, немного нерациорально, но тем не менее... Тогда еще последний вопрос остается: Кодировка - считывание из файла и вывод на экран русских букв без изменения самого файла...
Тогда еще последний вопрос остается: Кодировка - считывание из файла и вывод на экран русских букв без изменения самого файла...
Это уж сам в инете найдешь - вещь распространенная. Но я бы просто все файлы данных перекодировал, чтоб не заниматься постоянной перекодировкой при их чтении, тем более что cp1251 стандартная кодировка windows с 1995 года.
ЗЫ: Можно заменить номер цвета в файле данных на сам цвет в формате RGB (красный синий голубой), а потом определяй цвет для каждого региона так Region[i].color:=RGB(r,g,b); Компоненты цвета r,b,b - байты (0..255).
Автор: }0pa 28.11.2006 0:00
Не могу найти в инете ничего стоящего, Возможно это АПИ фукнции, а с ними я еще не сталкивался...
Код
CharToOEM/OEMToChar
Может что-нибудь это? Тогда что за тим PAnsiChar???
Автор: hiv 28.11.2006 14:02
Цитата(}0pa @ 27.11.2006 20:00)
Не могу найти в инете ничего стоящего, Возможно это АПИ фукнции, а с ними я еще не сталкивался...
Код
CharToOEM/OEMToChar
Может что-нибудь это? Тогда что за тим PAnsiChar???
Смотри DRKB (советую загрузить)
function StrToOem(const AnsiStr: string): string; begin SetLength(result, Length(AnsiStr)); if Length(result) > 0 then CharToOem(PChar(AnsiStr), PChar(result)) end;
Здесь win->dos , а наоборот сам переделаешь Удачи.
Автор: }0pa 29.11.2006 0:52
Большое Вам спасибо, что потратили время на эту задачу...Вроде все сделано. ЗЫ: Что такое DRKB?
Автор: hiv 29.11.2006 13:23
Цитата(}0pa @ 28.11.2006 20:52)
ЗЫ: Что такое DRKB?
Ну ты даешь!!! Смотри заголовок...
Автор: }0pa 29.11.2006 23:17
Тьфу,ты... Кстати,
Код
Attr:=$FFFFFFFF - faDirectory;
Означает, все файлы в текущей директории???
Автор: hiv 30.11.2006 13:29
Цитата(}0pa @ 29.11.2006 19:17)
Кстати,
Код
Attr:=$FFFFFFFF - faDirectory;
Означает, все файлы в текущей директории???
Абсолютно верно. Причем faAnyFile не хляет, вместо него $FFFFFFFF. А не хляет потому, что мелкософтовцы в винде повводили еще новых атрибутов - да еще и в инвертированом виде.
Автор: }0pa 1.12.2006 5:08
Код
{ if i=1 then begin //относительное смещение координат карты и формы на экране dX:=Region[i].Rect.Left; dY:=Region[i].Rect.Top; end else begin //выбираем минимальные значения if dX>Region[i].Rect.Left then dX:=Region[i].Rect.Left; if dY>Region[i].Rect.Top then dY:=Region[i].Rect.Top; end; }
Я сомневаюсь,что эта часть кода жизненно необходима Да, к тому же зачем вообще рисовать прямоугольник?
Автор: hiv 1.12.2006 13:36
Цитата(}0pa @ 1.12.2006 1:08)
Я сомневаюсь,что эта часть кода жизненно необходима
Необходима, если карты будут другие. Тогда смещения dx и dy, которые ты константами прописываешь в своей программе, прийдется менять, что повлечет перекомпиляцию кода. Тем более, что в этом коде используются все входные данные. Иначе зачем они тебе давались? Вспомни школьную физику или математику: "При решении задачи используются все данные, которые даны в условии, иначе задача решена НЕПРАВИЛЬНО!".
Цитата(}0pa @ 1.12.2006 1:08)
Да, к тому же зачем вообще рисовать прямоугольник?
Где ты видел рисование? TRect - просто стандартный объект, содержащий только координаты прямоугольной области.
Автор: }0pa 1.12.2006 20:44
Случилось самое страшное . Мне нужно организовать, чтобы карта рисовалась точно в области формы и при иземенения размера формы менялся ее размер
Автор: hiv 1.12.2006 21:49
Цитата(}0pa @ 1.12.2006 16:44)
Случилось самое страшное . Мне нужно организовать, чтобы карта рисовалась точно в области формы и при иземенения размера формы менялся ее размер
Тогда масштаб должен быть вещественным. Целочисленное деление DIV должно быть заменено вещественным /. Результируемые координаты должны быть округлены до целого. И тот кусок кода что выкинул - верни и доработай, чтоб масштаб вычислять.
Автор: Гость 2.12.2006 1:19
Нужно связать переменную m, отвечающую за масштаб с длиной и шириной формы, но другое дело, как это сделать?
Автор: }0pa 2.12.2006 1:20
Цитата
Тогда масштаб должен быть вещественным. Целочисленное деление DIV должно быть заменено вещественным /. Результируемые координаты должны быть округлены до целого.
А это я сделал, тем самым уменьшив шаг масштаба...
Автор: }0pa 4.12.2006 18:06
Еще требуется обратиться к каждому региону нажатием Левой кнопки мыши Вот не пойму как можно это сделать7
Автор: hiv 4.12.2006 21:54
Цитата(}0pa @ 4.12.2006 14:06)
Еще требуется обратиться к каждому региону нажатием Левой кнопки мыши Вот не пойму как можно это сделать7
Что значит обратиться? (поподробнее)
ЗЫ: Пересчитывай координаты мышки обратно в координаты карты, т.е. умножай на масштаб и добавляй смещение. Делать это по событию onMouseDown.
Автор: }0pa 5.12.2006 3:47
Обратиться. При нажатии на отдельный регион, появляется новая форма с этим регионом, но при этом этот регион в точности имеет размер формы и при Resize карта менят размеры.
Автор: hiv 5.12.2006 14:57
Главная проблема в определении принадлежности точки многоугольнику. Ее решение можешь посмотреть http://forum.pascal.net.ru/index.php?showtopic=3026&st=20&p=27912entry27912.
Автор: NTL 7.12.2006 22:26
Необходимо в этой же задаче: Дан рисунок, необходимо, создавая динмаически очередной ТАКОЙ же рисунок, разместить его в точке, где находится Райцентр. Вот мой вариант, но что-то не получается...Не отображается копия. Помогите плзю
Myimage.Left:=Round((Region[15].CenterX-dx-th div 2 - 1)/ m); Myimage.Top:= Round((Region[15].CenterY-dy-th div 2 - 1)/ m); MyImage.show;
Автор: NTL 8.12.2006 6:14
А как же связать масштаб с габаритами формы? Чтобы при изменении размера формы, карта была в точности размером формы?
Автор: hiv 8.12.2006 13:09
Цитата(NTL @ 8.12.2006 2:14)
А как же связать масштаб с габаритами формы? Чтобы при изменении размера формы, карта была в точности размером формы?
Очень просто: 1) Определяешь масштаб горизонтальный = размер региона по горизонтали / ширину формы; 2) Определяешь масштаб вертикальный = размер региона по вертикали / высоту формы; 3) Выбираешь из этих двух масштабов выбираешь максимальный.
ЗЫ: А причем тут растровая графика TImage? Ведь все время работали с векторной графикой!
Автор: NTL 8.12.2006 20:19
Цитата(hiv @ 8.12.2006 9:09)
ЗЫ: А причем тут растровая графика TImage? Ведь все время работали с векторной графикой!
Поподробнее не могли бы...
Автор: hiv 11.12.2006 13:23
Цитата(NTL @ 7.12.2006 18:26)
Необходимо в этой же задаче: Дан рисунок, необходимо, создавая динмаически очередной ТАКОЙ же рисунок, разместить его в точке, где находится Райцентр. Вот мой вариант, но что-то не получается...Не отображается копия. Помогите плзю
Нет! Это Вы поподробней: 1) Что за рисунок? Изображение региона мы сами рисуем по его координатам (это векторная графика) 2) Что значит разместить рисунок в точке? Это что - ужать его до такого состояния? Стандартные рисунки TImage (растровая графика) отображаются не в точке, а в прямоугольнике (который можно задавать типом TRect). 3) А где должна отображаться копия НЕИЗВЕСНОГО ТАКОГО ЖЕ рисунка?
Автор: NTL 11.12.2006 15:41
Вообщем, дан на форма Image1 с загруженным туда рисунком в формате BMP или Icon,например,красная точка (уж не знаю, есть ли разница BMP, ICON?). Нужно, не создавая компоненты Image2,Imege3...Image23 на стадии контруировании формы, создать эти компоненты во время работы программы и скопировать туда этот рисунок из Image1, затем вывести все эти рисунки на карту. Причем, каждый этот рисунок должен отобразиться в том месте, где находиться райцентр каждого района (ужимать ничего не надо, т.к.данный рисунок небольшой и в точности подходит к размерам нашего эллипса).В том примере, я пытался скопировать хотя бы в один рисунок, для общего слуачая понятно, что нужно будет array of TImage
Пересчитать обратно координаты так?
Код
for i:=0 to 23 do for j:=0 to length(Region[i].bounds)-1 do Region[i].bounds[j].X:=Round((bounds[j].X+dx)* m)
Цитата
1) Определяешь масштаб горизонтальный = размер региона по горизонтали / ширину формы; 2) Определяешь масштаб вертикальный = размер региона по вертикали / высоту формы; 3) Выбираешь из этих двух масштабов выбираешь максимальный.
Насчет масштаба, как определить размер всей карты? Я пытался подобрать,вроде так...
Код
if 1435/Form1.ClientWidth>854/Form1.ClientHeight then m:=1435/Form1.ClientWidth else m:=854/Form1.ClientHeight;
Автор: hiv 11.12.2006 16:37
Вместо
Canvas.Ellipse((Region[i].CenterX-x-th div 2 - 1)div m,(Region[i].CenterY-y-th div 2 - 1)div m,(Region[i].CenterX-x+ th div 2)div m,(Region[i].CenterY-y+ th div 2)div m);
напиши
Canvas.Draw((Region[i].CenterX-x) div m - Image1.Picture.Graphic.Width div 2, (Region[i].CenterY-y) div m - Image1.Picture.Graphic.Height div 2, Image1.Picture.Graphic.);
и не забудь поставить свойство Transparent=true у объекта Image1.
Цитата
Насчет масштаба, как определить размер всей карты? Я пытался подобрать,вроде так...
Ничего подбирать не нужно! Я тебе говорил переделать код выделенный тобой как ненужный в посте 26! Тебе надо дополнительно выбрать максимальные значения. Имея также минимальные ... если подумать! ... то будешь знать размер твоей карты (в масштабе 1:1).
Автор: NTL 11.12.2006 21:11
Цитата
Код
Canvas.Draw((Region[i].CenterX-x) div m - Image1.Picture.Graphic.Width div 2, (Region[i].CenterY-y) div m - Image1.Picture.Graphic.Height div 2, Image1.Picture.Graphic.);
для m:real; не подходит, а для целого в самый раз (гениальный вариант). Для вещественного никак нельзя? А насчет пересчитывания координат из предыдущего поста, ничего не можете подсказать?
Автор: NTL 11.12.2006 21:22
Тьфу ты Для m - любого дошло до меня...А вот насчет персчитывания координат мыши в координаты карты?
Автор: NTL 11.12.2006 21:45
Цитата(}0pa @ 1.12.2006 1:08)
Код
{ if i=1 then begin //относительное смещение координат карты и формы на экране dX:=Region[i].Rect.Left; dY:=Region[i].Rect.Top; end else begin //выбираем минимальные значения if dX>Region[i].Rect.Left then dX:=Region[i].Rect.Left; if dY>Region[i].Rect.Top then dY:=Region[i].Rect.Top; end; }
Почему именно i:=1
Автор: hiv 12.12.2006 13:48
Цитата(NTL @ 11.12.2006 17:45)
Почему именно i:=1
Если dX и dY не будут определены (как это делается на первом шаге), то не понятно к чему приведут сравнения dX>Region[i].Rect.Left и dY>Region[i].Rect.Top.
Цитата
А вот насчет персчитывания координат мыши в координаты карты?
Смотри снова пост 38. Что непонятного?
Автор: NTL 12.12.2006 18:30
Цитата
Смотри снова пост 38. Что непонятного?
Мне собственно нужно теперь обратиться к этой карте, в частности нажатие на тот самый райцентр с рисунком и нажатие на любой район, чтобы в заголовке формы появилось название района. Т.е, по-моему,.координаты мыши нужно преобразовать или я ошибаюсь...
Цитата(hiv @ 12.12.2006 9:48)
Если dX и dY не будут определены (как это делается на первом шаге), то не понятно к чему приведут сравнения dX>Region[i].Rect.Left и dY>Region[i].Rect.Top.
Но у нас же условие будет проверяться только один раз, когда :=1...Т.е. только один раз будет сравниваться
Автор: NTL 12.12.2006 19:19
К райцентру я смог обратитьсяся, мб немного неоптимально, но собсвена вот//
Код
MasX[i]:= Round((Region[i].CenterX-dx) / m) - round((Image1.Picture.Graphic.Width) / 2); MasY[i]:= Round((Region[i].CenterY-dy) / m) - Image1.Picture.Graphic.Height div 2; Canvas.Draw(MasX[i],MasY[i],Image1.Picture.Graphic); --------------------------------------------------------------- if (x>=MasX[i])and (x<=MasX[i]+image1.Picture.Width) and (y>=MasY[i])and(y<=MasY[i]+image1.Picture.height) then label2.caption:=Region[i].Name;
Осталось только к самому региону...Может подскажете?
Автор: NTL 12.12.2006 19:39
Цитата(NTL @ 12.12.2006 14:30)
Но у нас же условие будет проверяться только один раз, когда :=1...Т.е. только один раз будет сравниваться
Вопрос снимается, дошло
Автор: NTL 12.12.2006 19:50
Может быть, что-нибудь похожее...рез-ат этого почти правильный, но погрешносить все еще велика. Как бы ее свести к минимуму?
Код
if (x>=Round(Region[i].Rect.Left-dx)/m) and (x<=round(Region[i].Rect.Right-dx)/m) and (y<=round(Region[i].Rect.Bottom-dy)/m) and (y<=round(Region[i].Rect.Top-dy)/m) then label1.Caption:=region[i].Center;
ЗЫ: Принадлежность точки к многоугольнику рассмотрел, но слишком это сложный вариант
Автор: hiv 12.12.2006 20:34
Цитата(NTL @ 12.12.2006 15:50)
ЗЫ: Принадлежность точки к многоугольнику рассмотрел, но слишком это сложный вариант
Пилите Шура - пилите... (Ильф Петров) По другому не получиться.
Автор: NTL 12.12.2006 20:57
При нажатии на райцентр - новая форма и рисование ТОЛЬКО одного соответствующего района
Цитата(hiv @ 12.12.2006 16:34)
Пилите Шура - пилите... (Ильф Петров) По другому не получиться.
Не...Как бы обратиться к прямоугольнику этого района
Автор: NTL 14.12.2006 12:50
С этой задачей справился, осталось немного- при нажатии на регион, создавалася новая форма и там вырисовывался этот регион только один
Автор: z12 15.01.2007 23:22
Цитата(NTL @ 14.12.2006 8:50)
С этой задачей справился, осталось немного- при нажатии на регион, создавалася новая форма и там вырисовывался этот регион только один
простейшим вариантом будет, узнать индекс региона, открыть форму(добавиш в проект), в процедуре создания формы выполни тоже самое что и делает главная форма, тока открывать надо файл с индексом региона (поидее индекс в массиве будет равен, номеру файла при поиске в папке, кароче в цикле ищещ файлы, как тока итерация равна индексу региона грузиш файл прерываеш цикл), дальше сам
надеюсь не запутано объяснил =) я кстате чутка переписал эту софтину, убрал мерцание при перерисовке если надо вылажу код