Maintaining osm.xml

I wanted to change the way some roads are presented on my maps. Here is how I did that.
The first step is to get current, like this:


Rename existing folder 'openstreetmap-carto' containing osm.xml to some recovery place.
Make new folder 'openstreetmap-carto'
cd there
git clone https://github.com/gravitystorm/openstreetmap-carto.git
This will make directory ../openstreetmap-carto/openstreetmap-carto. 
cd there
./get-shapefiles.sh				Time consuming
carto -l project.mml > osm.xml		This will make the recent version of osm.xml
 

My maintenance issue was roads that became indistinct as zoom level was reduced, but still were important features in the wilds of Nevada to zoom 12. A zoom12 view may cover a 20x30 mile area over the ground and to be able to see where the roads are on that ground is useful. I wanted to change how a road entity was presented at some zoom level.
The first task is to determine what the entity type is:


1) Draw a box that the entity passes through. Use the max and min coordinates of that box in the SELECT below.
2) psql gis	(postgres running of course)
then

SELECT *,St_AsText(way)  FROM planet_osm_line where ST_Intersects(way, St_SetSRID(St_MakeBox2D(St_SetSRID(St_Point(-13348046.00, 4864100.00),900913)::geometry, St_SetSRID(St_Point(-13347721.00, 4863546.00),900913)),900913)::geometry) is true;

where the coordinates are of the box from 1).

3)If you are lucky a single row (or few) will be returned by query. From that you should be able to determine the type of the entity you are interested in. In the case at hand it was highway, residential. A miss classification given where it is.
Now that you know what you are looking for, the question becomes which of the 35,000+ lines in osm.xml affect the entity you looking at. There are 82 layers described there and 169 occurrences of the term ‘residential’. So, which ones are those that I seek?
To find out I wrote a small program to index osm.xml by two terms.


//////////////////////////////////////////////The header
#ifndef OSMXMLINDEX_H
#define OSMXMLINDEX_H

#include <QtGui/QtGui>
#include <QMainWindow>
#include <qlabel.h>
#include <qlineedit.h>
#include <qplaintextedit.h>
#include <qmessagebox.h>
class osmXmlIndex : public QMainWindow
{
    Q_OBJECT
public:
    osmXmlIndex(QApplication *);
    ~osmXmlIndex();
private:
    QWidget         *CentralWidget;
    QLabel          *LabelIndexTerm;   //does not show
    QLineEdit       *LabelIndexEdit;
    QLineEdit       *LabelIndexEdi2;
    QPlainTextEdit  *IndexDisplay;
private slots:
    void slotDisplayIndex(void);
};
#endif // OSMXMLINDEX_H
///////////////////////////////////////////////////////and the code
#include "osmxmlindex.h"

osmXmlIndex::osmXmlIndex(QApplication *App) :  QMainWindow()
{
    QWidget* w = new QWidget(this);
    setCentralWidget(w);
    CentralWidget = this;
    setWindowTitle("osmIndex : Version 11/28/2015");
    int wHeight = 950;
    int wWidth = 1000;
    setGeometry(10, 10, wWidth, wHeight);
    LabelIndexTerm = new QLabel("Index Term",this);
    LabelIndexTerm->setGeometry(10, 10, 70, 20);
    LabelIndexTerm->setVisible(true);
    LabelIndexEdit = new QLineEdit("",this);
    LabelIndexEdit->setGeometry(90, 10, 200, 20);
    LabelIndexEdit->setVisible(true);
    connect(LabelIndexEdit, SIGNAL(returnPressed()), this, SLOT(slotDisplayIndex()));
    LabelIndexEdi2 = new QLineEdit("",this);
    LabelIndexEdi2->setGeometry(300, 10, 200, 20);
    LabelIndexEdi2->setVisible(true);
    connect(LabelIndexEdi2, SIGNAL(returnPressed()), this, SLOT(slotDisplayIndex()));
    IndexDisplay = new QPlainTextEdit("",this);
    IndexDisplay->setGeometry(0, 40, wWidth, wHeight - 40);
    IndexDisplay->setVisible(true);
}
void osmXmlIndex::slotDisplayIndex(void)
{
    IndexDisplay->clear();
    int     lineCount = 0, t1Count = 0, t2Count = 0;
    QString rpt;
    QString xmlFilePath;
    QFile   osmXmlFile("/home/RB/proj/Maps/MapWorking/openstreetmap-carto/openstreetmap-carto/osm.xml");
    if (!osmXmlFile.open(QIODevice::ReadOnly | QIODevice::Text))
    {
      QMessageBox::information(this, tr("FTP"), tr("Unable to openFile  "
                                           "%1.").arg(xmlFilePath));
      return;
    }
    while (!osmXmlFile.atEnd())
    {
        QString osmXmlData;
        lineCount++;
        osmXmlData = osmXmlFile.readLine();
        if (osmXmlData.contains(LabelIndexEdit->text(), Qt::CaseInsensitive))
        {
            rpt = QString("%1").arg(lineCount, 6) + ": " + osmXmlData.left(osmXmlData.length()-1);
            IndexDisplay->appendPlainText(rpt);
            t1Count++;
            continue;
        }
        if ((LabelIndexEdi2->text().length() > 0) && osmXmlData.contains(LabelIndexEdi2->text(), Qt::CaseInsensitive))
        {
            rpt = QString("        %1").arg(lineCount, 6) + ": " + osmXmlData.left(osmXmlData.length()-1);
            IndexDisplay->appendPlainText(rpt);
            t2Count++;
            continue;
        }
    }
    rpt = QString(" Term 1 count %1 : Term 2 count %2").arg( t1Count, 6).arg(t2Count, 6);
    IndexDisplay->appendPlainText(rpt);
}
osmXmlIndex::~osmXmlIndex()
{
}

The output from that program looks like


.......
 10628: <Layer name="line-barriers"
 10666: <Layer name="cliffs"
 10708: <Layer name="area-barriers"
 10739: <Layer name="ferry-routes"
         10852:     <Filter>([int_tc_type] = 'residential')</Filter>
         10858:     <Filter>([int_tc_type] = 'residential')</Filter>
         10864:     <Filter>([int_tc_type] = 'residential')</Filter>
         10870:     <Filter>([int_tc_type] = 'residential')</Filter>
         10876:     <Filter>([int_tc_type] = 'residential')</Filter>
 10916:   <Layer name="turning-circle-casing"
         10933:       ('residential', 3),
         10997:     <Filter>([feature] = 'highway_residential')</Filter>
 11001: <Layer name="highway-area-casing"
......

Were I working on a turning circle casing I would direct my interest to the vicinity of lines 10852, 10858, etc. (styles preceed their layers). And, thus I found the lines affecting the presentation I wanted to change
-RickBrown in Reno, NV

Interesting. There’s been discussion elsewhere about the “over-complexity” of the current OSM-Carto style. The fact that you’re having to write code to analyse it kind of bears that out :slight_smile:

However, maybe I’m misunderstanding what you’re doing, but you’re not directly modifying the osm.xml are you? “roads.mss” in the OSM Carto source is around 3k lines - that’s still large, but it’s less than the 33k of osm.xml. Would it not be easier to “borrow” some of the tertiary settings in there and apply to “residential”?

I am working in the osm.xml file. The problem with the .mss files for me is, first my lack of understanding of them and they are pretty obscure in their own right. Second is I have other things going on in my osm.xml that the .mss files know nothing about; contour interval display for example. After every ‘carto -l project.mml > osm.xml’ I need to put my custom stuff back in. So I don’t do a wholesale update very often.
I have another post coming up on making osm.xml more readable. I’ll send it along shortly
-Rick