You can export point, line, and polygon layers into separate files and combine them with ogr2ogr.
Test data
points.mif
Version 300
Charset "Neutral"
Delimiter ","
Columns 2
R_G_B Char(254)
COLOR Char(254)
Data
Point -90.5566923029394 14.5906248310583
Symbol (35,0,12)
Point -90.5515144114431 14.6013641615691
Symbol (35,0,12)
Point -90.5407750809323 14.5938849849634
Symbol (35,0,12)
lines.mif
Version 300
Charset "Neutral"
Delimiter ","
Columns 2
R_G_B Char(254)
COLOR Char(254)
Data
Line -90.5439393479578 14.6041448810763 -90.5314740536149 14.6133500215141
Pen (1,2,9288960)
Line -90.5536239227934 14.6182402523717 -90.5630208369904 14.6045284285946
Pen (1,2,9288960)
Line -90.557651171735 14.5991587633392 -90.5396244383776 14.5850633920438
Pen (1,2,9288960)
polygons.mif
Version 300
Charset "Neutral"
Delimiter ","
Columns 2
R_G_B Char(254)
COLOR Char(254)
Data
Region 1
4
-90.5361725107134 14.6028024647625
-90.5243784245275 14.6012682746895
-90.5358848500747 14.5908166048174
-90.5361725107134 14.6028024647625
Pen (1,2,0)
Brush (2,255)
Region 1
4
-90.5701164660778 14.5969533651093
-90.5593771355671 14.5942685324816
-90.5737601675012 14.5838168626095
-90.5701164660778 14.5969533651093
Pen (1,2,0)
Brush (2,255)
Region 1
4
-90.5453776511512 14.6222675013133
-90.533200017447 14.6205415374812
-90.5498843344906 14.6101857544886
-90.5453776511512 14.6222675013133
Pen (1,2,0)
Brush (2,255)
ogr2ogr commands for combining points, lines, and polygons into layer "collect"
ogr2ogr -f "MapInfo File" collect.tab points.mif -nln collect
ogr2ogr -f "MapInfo File" -update -append collect.tab lines.mif -nln collect
ogr2ogr -f "MapInfo File" -update -append collect.tab polygons.mif -nln collect
ogrinfo that confirms that all features with individual styles are now on the same layer
ogrinfo collect.tab -al
INFO: Open of `collect.tab'
using driver `MapInfo File' successful.
Layer name: collect
Geometry: Unknown (any)
Feature Count: 9
Extent: (-90.570000, 14.580000) - (-90.510000, 14.620000)
Layer SRS WKT:
ENGCRS["Nonearth",
EDATUM[""],
CS[Cartesian,2],
AXIS["(E)",east,
ORDER[1],
LENGTHUNIT["Meter",1]],
AXIS["(N)",north,
ORDER[2],
LENGTHUNIT["Meter",1]]]
Data axis to CRS axis mapping: 1,2
R_G_B: String (254.0)
COLOR: String (254.0)
OGRFeature(collect):1
R_G_B (String) = FF0000
COLOR (String) = 1
Style = SYMBOL(a:0,c:#000000,s:12pt,id:"mapinfo-sym-35,ogr-sym-9")
POINT (-90.57 14.6)
OGRFeature(collect):2
R_G_B (String) = FF0000
COLOR (String) = 1
Style = SYMBOL(a:0,c:#000000,s:12pt,id:"mapinfo-sym-35,ogr-sym-9")
POINT (-90.54 14.6)
OGRFeature(collect):3
R_G_B (String) = FF0000
COLOR (String) = 1
Style = SYMBOL(a:0,c:#000000,s:12pt,id:"mapinfo-sym-35,ogr-sym-9")
POINT (-90.54 14.6)
OGRFeature(collect):4
R_G_B (String) = 8DBD00
COLOR (String) = 62
Style = PEN(w:1px,c:#8dbd00,id:"mapinfo-pen-2,ogr-pen-0",cap:r,j:r)
LINESTRING (-90.54 14.61,-90.54 14.61)
OGRFeature(collect):5
R_G_B (String) = 8DBD00
COLOR (String) = 62
Style = PEN(w:1px,c:#8dbd00,id:"mapinfo-pen-2,ogr-pen-0",cap:r,j:r)
LINESTRING (-90.54 14.62,-90.57 14.61)
OGRFeature(collect):6
R_G_B (String) = 8DBD00
COLOR (String) = 62
Style = PEN(w:1px,c:#8dbd00,id:"mapinfo-pen-2,ogr-pen-0",cap:r,j:r)
LINESTRING (-90.57 14.6,-90.54 14.58)
OGRFeature(collect):7
R_G_B (String) = 0000FF
COLOR (String) = 5
Style = BRUSH(fc:#0000ff,id:"mapinfo-brush-2,ogr-brush-0");PEN(w:1px,c:#000000,id:"mapinfo-pen-2,ogr-pen-0",cap:r,j:r)
POLYGON ((-90.54 14.61,-90.51 14.6,-90.54 14.6,-90.54 14.61))
OGRFeature(collect):8
R_G_B (String) = 0000FF
COLOR (String) = 5
Style = BRUSH(fc:#0000ff,id:"mapinfo-brush-2,ogr-brush-0");PEN(w:1px,c:#000000,id:"mapinfo-pen-2,ogr-pen-0",cap:r,j:r)
POLYGON ((-90.57 14.6,-90.57 14.6,-90.57 14.58,-90.57 14.6))
OGRFeature(collect):9
R_G_B (String) = 0000FF
COLOR (String) = 5
Style = BRUSH(fc:#0000ff,id:"mapinfo-brush-2,ogr-brush-0");PEN(w:1px,c:#000000,id:"mapinfo-pen-2,ogr-pen-0",cap:r,j:r)
POLYGON ((-90.54 14.62,-90.54 14.62,-90.54 14.61,-90.54 14.62))
Best Answer
If the styling of elements is thematic (and you know what columns drive the theme) you can build a QML file programmatically in PostgreSQL.
For example, I have a file with ~150 styles for government zone polygons (subsets of the zones have the same style). The data was originally in MapInfo format in two TAB files - one with the zone polygons, another with aspatial data like zone_code, description, group, and lastly 'red', 'green' 'blue' (the last 3 are the RGB values for the recommended colour ramp).
To create my QML file, I did the following:
(1) import the data into PostgreSQL (using ogr2ogr);
(2) write a python script that looks like this -
The script is kludgy (there's no need for the
for row in cursor
sincecursor
only returns one row), but result is exactly what I wanted: a QML file that I could distribute to my colleagues so that they could style Zoned data with 3 clicks. (Bonus benefit: when theme files need to be built for different sets of categories, only the query has to change: we have ~25 different theme sets, and they were all constructed from that one script by changing the query and the destination file).The output looks like this -
For your specific theme you would have to write the appropriate query (which means you need to know the columns that 'drive' the style categories).
MapInfo stupidly stores styling data row-by-row (the 90s called, they want their 'style and content mixed' back), but it can be retrieved if you add the a -SQL statement to your ogr2ogr import statement adding OGR_STYLE to the retrieved set. You can then parse the 'style' column in PostgreSQL to get the styling information out.
This is the script that I use to import all TAB files in a given directory (the slashes are just to show that it's one line, broken up for clarity): the relevant additional bit is the -SQL line.
If you then look at the imported data, you will find a column 'style' that has entries that look like
For point data it will look different, of course - it'll probably have marker types and what-not.
In all likelihood, someone with a better knowledge of how style information is stored in "the Windows 8 of GIS" (MapInfo) would be able to tell you how to get the specific colour and symbol information more directly in the -SQL statement (I've been meaning to find out, but I try to think about MapInfo as little as possible: I find it easy enough to automatically parse the 'style' column in PostgreSQL with a script).