⬆️ ⬇️

Working with ShapeFile (* .shp) in Delphi

During the work I faced the task of reading files with the extension ".shp". The information that I found on the Internet was fragmented and vague, and therefore I decided to combine what I had to reach on my own and tell you.



Formulation of the problem



We have a file with the extension ".shp". This file contains a map in the form of contours: each contour is made by a separate shape; the name of the shape is the height characteristic of the isoline. Our task will be to take the data from this into an array. An array is a set of points defined by three coordinates (x, y, z). Further, this array must be entered into the database, but this time we will miss out of consideration.



A bit of theory



Consider the features of the "* .shp" format that are important to us. In fact, ShapeFile contains a lot of information, but we have a narrow interest. First, we need to know that ShapeFile is divided into so-called "Shapes" (English Shape - Figure). A shape is a shape or set of shapes (possibly unrelated) of complex shapes. The shape is stored in the form of individual points and information about the lines connecting them. In our case, each shape is a continuous curve denoting the position of points of the terrestrial landscape of the same height (the name of the shape corresponds to the numerical value of the height). In view of the specificity of the task, we will not be interested in information about the lines connecting the points, but only information about the position of the points and their height.

')

It is also worth noting that, together with the file "* .shp", the file format "* .dbf" is generated containing header information about our shapes. The file "* .dbf" should have the same name as the file ".shp".



MapWindowGIS



After some searching on the net, I discovered the MapWindowGIS library. The possibilities of this library are very wide and it will help us in achieving our goals. You can download it at the following link .



After you download this library you need to install it. After installation, run the Delphi development environment. Execute the Component-Import AciveX Control ... command and the window will appear:

image



In the list of ActiveX libraries we find - MapWinGIS Component and click on the “Install ...” button, after which you need to install this library as a normal component. After successful installation of this library, the TMap component will appear on the ActiveX tab.



Add a map display



To begin with, add a Map1 type TMap component to the form. As already mentioned, it is in the last position of the ActiveX tab.



In order for our component to display the map contained in our file, rather simple code:



var



shp:Shapefile; // -

HandleLayer:integr; //



begin



shp:=CoShapefile.Create; // -

shp.Open('map.shp',nil); // 'map.shp'

Map1.Focused; // ,

HandleLayer:=Map1.AddLayer(shp,true); //

Map1.ZoomToMaxExtents; // ( ) ,



end;




Reading shape header information



To read the header information from the "* .dbf" file, we will use the TTable and TDataSource components. To do this, we add to the form the components Table1 of type TTable and DataSource1 of type TDataSource from the tabs “BDE” and “Data Access”, respectively. The Table1 component is left unchanged, and in the DataSource1 component, in the “DataSet” parameter, select “Table1”.



For convenience, we add a TOpenDialog type OpenDialog1 component from the Dialogs tab to the form. In the “Filter” parameter of the OpenDialog1 component, we add a filter with the name “Shape files (.shp)” and filtering “* .shp” (without quotes). In addition, we will add the Open and Save buttons.



The complete procedure code for the “Open” button will look like this:



procedure TImportForm.ShowShape;



var



nameDB:WideString; //

HandleLayer:integr;



begin



nameDB:=OpenDialog1.FileName; //

shp:=CoShapefile.Create;

shp.Open(nameDB,nil);

Map1.Focused;

HandleLayer:=Map1.AddLayer(shp,true);

Map1.ZoomToMaxExtents;



Delete(nameDB,length(nameDB)-2,3); //

nameDB:=nameDB+'dbf'; // ".dbf"

Table1.TableName:=nameDB; // "*.dbf"

Table1.Active:=True; //""



end;




Do not forget that the shp variable must be added to the global variables section.



Read points from file



To begin, I will give the procedure code assigned to the “Save” button:



procedure TImportForm.SaveShape;



var



i,j:integer; //

z:integer; // ,



begin



if shp<>nil then // shp

begin



Table1.First; //

k:=0;

for i:=0 to shp.NumShapes-1 do //

begin

z:=StrToInt(Table1.Fields[2].Value); //

for j:=0 to shp.Shape[i].numPoints-1 do //

begin

Mas[k].x:=shp.Shape[i].Point[j].x;

Mas[k].y:=shp.Shape[i].Point[j].y;

Mas[k].z:=z;

inc(k);

end;

Table1.Next; //

end;

..

//

..



end

else ShowMessage(' ');

end;




Let's look at some of the features. So, Mas is a one-dimensional array of points having three parameters of type Double (x, y, z). The shp.NumShapes parameter is equal to the number of shapes inside the file. The parameter Table1.Fields [2] .Value is the name of the current shape (the "* .dbf" file is arranged in such a way that the name is written in the 3rd column). shp.Shape [i] .numPoints, as you probably already guessed - the number of points in the i-volume shape. shp.Shape [i] .Point [j] .x and shp.Shape [i] .Point [j] .y are the same treasured coordinates of the j-th point of the i-th shape. The rest, I think, is clear from the comments.



Conclusion



So, we’ve finished looking at how to work with ShapeFile in the Delphi environment. We coped with the task completely. Of course, this review is only the tip of the iceberg, but I hope this introductory article will help you in further development of this direction.



Materials used:

Work with MapWindow GIS. Overview

Source: https://habr.com/ru/post/123394/



All Articles