From 576c60234503f5a3c5a00e6bfc5055d2ccc54c5d Mon Sep 17 00:00:00 2001 From: Fernando Erd <fce15@inf.ufpr.br> Date: Wed, 27 Jun 2018 11:37:39 -0300 Subject: [PATCH] Add transport indicator --- src/libs/routes/api.js | 3 + src/libs/routes/transport.js | 468 +++++++++++++++++++++++++++++++++++ 2 files changed, 471 insertions(+) create mode 100644 src/libs/routes/transport.js diff --git a/src/libs/routes/api.js b/src/libs/routes/api.js index 2f9e7f4a..70311ae0 100644 --- a/src/libs/routes/api.js +++ b/src/libs/routes/api.js @@ -64,6 +64,8 @@ const outOfSchool = require(`${libs}/routes/outOfSchool`); const classroomCount = require(`${libs}/routes/classroomCount`); +const transport = require(`./transport`); + const dailyChargeAmount = require(`${libs}/routes/dailyChargeAmount`); api.get('/', (req, res) => { @@ -101,5 +103,6 @@ api.use('/siope', siope); api.use('/out_of_school', outOfSchool); api.use('/classroom_count', classroomCount); api.use('/daily_charge_amount', dailyChargeAmount); +api.use('/transport', transport); module.exports = api; diff --git a/src/libs/routes/transport.js b/src/libs/routes/transport.js new file mode 100644 index 00000000..7af1b990 --- /dev/null +++ b/src/libs/routes/transport.js @@ -0,0 +1,468 @@ +const express = require('express'); + +const transportApp = express.Router(); + +const libs = `${process.cwd()}/libs`; + +const log = require(`${libs}/log`)(module); + +const squel = require('squel'); + +const query = require(`${libs}/middlewares/query`).query; + +const multiQuery = require(`${libs}/middlewares/multiQuery`); + +const response = require(`${libs}/middlewares/response`); + +const addMissing = require(`${libs}/middlewares/addMissing`); + +const id2str = require(`${libs}/middlewares/id2str`); + +const ReqQueryFields = require(`${libs}/middlewares/reqQueryFields`); + +const config = require(`${libs}/config`); + +const cache = require('apicache').options({ debug: config.debug, statusCodes: {include: [200]} }).middleware; + +let rqf = new ReqQueryFields(); + +transportApp.use(cache('15 day')); + +transportApp.get('/year_range', (req, res, next) => { + req.sql.from('matricula') + .field('MIN(matricula.ano_censo)', 'start_year') + .field('MAX(matricula.ano_censo)', 'end_year'); + next(); +}, query, response('range')); + +transportApp.get('/years', (req, res, next) => { + req.sql.from('matricula') + .field('DISTINCT matricula.ano_censo', 'year'); + next(); +}, query, response('years')); + +transportApp.get('/adm_dependency', (req, res, next) => { + req.result = []; + for(let i = 1; i <= 4; ++i) { + req.result.push({ + id: i, + name: id2str.admDependency(i) + }); + }; + next(); +}, response('adm_dependency')); + +transportApp.get('/adm_dependency_detailed', (req, res, next) => { + req.result = []; + for(let i = 1; i <= 6; ++i) { + req.result.push({ + id: i, + name: id2str.admDependencyPriv(i) + }); + }; + next(); +}, response('adm_dependency_detailed')); + +transportApp.get('/location', (req, res, next) => { + req.result = [ + {id: 1, name: 'Urbana'}, + {id: 2, name: 'Rural'} + ]; + next(); +}, response('location')); + +transportApp.get('/rural_location', (req, res, next) => { + req.result = [ + {id: 1, name: "Urbana"}, + {id: 2, name: "Rural"}, + {id: 3, name: "Rural - Ãrea de assentamento"}, + {id: 4, name: "Rural - Terra indÃgena"}, + {id: 5, name: "Rural - Ãrea remanescente de quilombos"}, + {id: 6, name: "Rural - Unidade de uso sustentável"} + ]; + next(); +}, response('rural_location')); + +transportApp.get('/education_level_basic', (req, res, next) => { + req.result = [ + {id: null, name: 'Não classificada'}, + {id: 1, name: 'Creche'}, + {id: 2, name: 'Pré-Escola'}, + {id: 4, name: 'Ensino Fundamental - anos iniciais'}, + {id: 5, name: 'Ensino Fundamental - anos finais'}, + {id: 6, name: 'Ensino Médio'} + ]; + next(); +}, response('education_level_basic')); + +transportApp.get('/transportation_manager', (req, res, next) => { + req.result = [ + {id: null, name: 'Não classificada'}, + {id: 1, name: 'Estadual'}, + {id: 2, name: 'Municipal'}, + ]; + next(); +}, response('transportation_manager')); + +transportApp.get('/source', (req, res, next) => { + req.sql.from('fonte') + .field('fonte', 'source') + .where('tabela = \'matricula\''); + next(); +}, query, response('source')); + +rqf.addField({ + name: 'filter', + field: false, + where: true +}).addField({ + name: 'dims', + field: true, + where: false +}).addValue({ + name: 'city', + table: 'municipio', + tableField: 'nome', + resultField: 'city_name', + where: { + relation: '=', + type: 'integer', + field: 'municipio_id', + table: 'matricula' + }, + join: { + primary: 'id', + foreign: 'municipio_id', + foreignTable: 'matricula' + } +}).addValue({ + name: 'state', + table: 'estado', + tableField: 'nome', + resultField: 'state_name', + where: { + relation: '=', + type: 'integer', + field: 'estado_id', + table: 'matricula' + }, + join: { + primary: 'id', + foreign: 'estado_id', + foreignTable: 'matricula' + } +}).addValue({ + name: 'rural_location', + table: 'matricula', + tableField: 'localidade_area_rural', + resultField: 'rural_location_id', + where: { + relation: '=', + type: 'integer', + field: 'localidade_area_rural' + } +}).addValue({ + name: 'location', + table: 'matricula', + tableField: 'localizacao_id', + resultField: 'location_id', + where: { + relation: '=', + type: 'integer', + field: 'localizacao_id' + } +}).addValue({ + name:'adm_dependency', + table: 'matricula', + tableField: 'dependencia_adm_id', + resultField: 'adm_dependency_id', + where: { + relation: '=', + type: 'integer', + field: 'dependencia_adm_id' + } +}).addValue({ + name: 'adm_dependency_detailed', + table: 'matricula', + tableField: 'dependencia_adm_priv', + resultField: 'adm_dependency_detailed_id', + where: { + relation: '=', + type: 'integer', + field: 'dependencia_adm_priv' + } +}).addValue({ + name: 'transportation_manager', + table: 'matricula', + tableField: 'responsavel_transp', + resultField: 'transportation_manager_id', + where: { + relation: '=', + type: 'integer', + field: 'responsavel_transp' + } +}).addValue({ + name: 'education_level_basic', + table: 'matricula', + tableField: 'etapas_mod_ensino_segmento_id', + resultField: 'education_level_basic_id', + where: { + relation: '=', + type: 'integer', + field: 'etapas_mod_ensino_segmento_id' + } +}).addValue({ + name: 'service_type', + table: 'matricula', + tableField: 'tipo', + resultField: 'service_type_id', + where: { + relation: '=', + type: 'integer', + field: 'tipo' + } +}).addValue({ + name: 'service_type', + table: 'matricula', + tableField: 'tipo', + resultField: 'service_type_id', + where: { + relation: '=', + type: 'integer', + field: 'tipo' + } +}).addValue({ + name: 'min_year', + table: 'matricula', + tableField: 'ano_censo', + resultField: 'year', + where: { + relation: '>=', + type: 'integer', + field: 'ano_censo' + } +}).addValue({ + name: 'max_year', + table: 'matricula', + tableField: 'ano_censo', + resultField: 'year', + where: { + relation: '<=', + type: 'integer', + field: 'ano_censo' + } +}); + +function matchQueries(queryTotal, queryPartial) { + let match = []; + queryTotal.forEach((result) => { + let newObj = {}; + let keys = Object.keys(result); + keys.forEach((key) => { + newObj[key] = result[key]; + }); + let index = keys.indexOf('total'); + if(index > -1) keys.splice(index, 1); + let objMatch = null; + + for(let i = 0; i < queryPartial.length; ++i) { + let partial = queryPartial[i]; + let foundMatch = true; + for(let j = 0; j < keys.length; ++j) { + let key = keys[j]; + if(partial[key] !== result[key]) { + foundMatch = false; + break; + } + } + if(foundMatch) { + objMatch = partial; + break; + } + } + + if(objMatch) { + newObj.percentage = (objMatch.total / result.total) * 100; + newObj.partial = objMatch.total; + newObj.total = result.total + match.push(newObj); + } + }); + + return match; +} + +transportApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => { + req.querySet = []; + req.queryIndex = {}; + + let allEnrollment = req.sql.clone() + allEnrollment.field('COUNT(*)', 'total') + .field("'Brasil'", 'name') + .field('matricula.ano_censo', 'year') + .from('matricula') + .group('matricula.ano_censo') + .order('matricula.ano_censo') + .where('matricula.tipo <= 3'); + req.queryIndex.allEnrollment = req.querySet.push(allEnrollment) - 1; + + let allEnrollmentTransport = req.sql.clone() + allEnrollmentTransport.field('COUNT(*)', 'total') + .field("'Brasil'", 'name') + .field('matricula.ano_censo', 'year') + .field('matricula.transporte_escolar_publico', 'use_transport_id') + .from('matricula') + .group('matricula.ano_censo') + .group('matricula.transporte_escolar_publico') + .order('matricula.ano_censo') + .where('matricula.tipo <= 3'); + req.queryIndex.allEnrollmentTransport = req.querySet.push(allEnrollmentTransport) - 1; + + + let allTransports = req.sql.clone() + allTransports.field('COUNT(*)', 'total') + .field("'Brasil'", 'name') + .field('matricula.ano_censo', 'year') + .from('matricula') + .group('matricula.ano_censo') + .order('matricula.ano_censo') + .where('matricula.tipo <= 3 AND matricula.transporte_escolar_publico = 1'); + req.queryIndex.allTransports = req.querySet.push(allTransports) - 1; + + // Vans e Kombi + let goVansAndKombi = allTransports.clone(); + goVansAndKombi.field('matricula.transporte_vans_kombi','use_transport_id') + goVansAndKombi.where('matricula.transporte_vans_kombi = 1 OR matricula.transporte_vans_kombi = 0'); + goVansAndKombi.group('matricula.transporte_vans_kombi'); + req.queryIndex.goVansAndKombi = req.querySet.push(goVansAndKombi) - 1; + + // Micro + let goMicroBus = allTransports.clone(); + goMicroBus.field('matricula.transporte_micro_onibus', 'use_transport_id') + goMicroBus.where('matricula.transporte_micro_onibus = 1 OR matricula.transporte_micro_onibus = 0'); + goMicroBus.group('matricula.transporte_micro_onibus'); + req.queryIndex.goMicroBus = req.querySet.push(goMicroBus) - 1; + + + // Ônibus + let goBus = allTransports.clone(); + goBus.field("matricula.transporte_onibus", 'use_transport_id') + goBus.where('matricula.transporte_onibus = 1 OR matricula.transporte_onibus = 0'); + goBus.group('matricula.transporte_onibus') + req.queryIndex.goBus = req.querySet.push(goBus) - 1; + + // Bicicleta + let goBikes = allTransports.clone(); + goBikes.field('matricula.transporte_bicicleta', 'use_transport_id') + goBikes.where('matricula.transporte_bicicleta = 1 OR matricula.transporte_bicicleta = 0'); + goBikes.group('matricula.transporte_bicicleta') + req.queryIndex.goBikes = req.querySet.push(goBikes) - 1; + + // Tração Animal + let goAnimalTraction = allTransports.clone(); + goAnimalTraction.field('matricula.transporte_animal', 'use_transport_id') + goAnimalTraction.where('matricula.transporte_animal = 1 OR matricula.transporte_animal = 0'); + goAnimalTraction.group('matricula.transporte_animal') + req.queryIndex.goAnimalTraction = req.querySet.push(goAnimalTraction) - 1; + + // Outro VeÃculo + let goOtherVehicle = allTransports.clone(); + goOtherVehicle.field('matricula.transporte_outro', 'use_transport_id') + goOtherVehicle.where('matricula.transporte_outro = 1 OR matricula.transporte_outro = 0'); + goOtherVehicle.group('matricula.transporte_outro') + req.queryIndex.goOtherVehicle = req.querySet.push(goOtherVehicle) - 1; + + // Aquaviário/ Embarcação (capacidade até 5 alunos) + let goWaterway_5_Students = allTransports.clone(); + goWaterway_5_Students.field('matricula.transporte_embar_0_5','use_transport_id') + goWaterway_5_Students.where('matricula.transporte_embar_0_5 = 1 OR matricula.transporte_embar_0_5 = 0'); + goWaterway_5_Students.group('matricula.transporte_embar_0_5') + req.queryIndex.goWaterway_5_Students = req.querySet.push(goWaterway_5_Students) - 1; + + // Aquaviário/ Embarcação (capacidade de 5 até 15 alunos) + let goWaterway_15_Students = allTransports.clone(); + goWaterway_15_Students.field('matricula.transporte_embar_5_15', 'use_transport_id') + goWaterway_15_Students.where('matricula.transporte_embar_5_15 = 1 OR matricula.transporte_embar_5_15 = 0'); + goWaterway_15_Students.group('matricula.transporte_embar_5_15') + req.queryIndex.goWaterway_15_Students = req.querySet.push(goWaterway_15_Students) - 1; + + // Aquaviário/ Embarcação (capacidade de 15 até 35 alunos)r + let goWaterway_35_Students = allTransports.clone(); + goWaterway_35_Students.field('matricula.transporte_embar_15_35', 'use_transport_id') + goWaterway_35_Students.where('matricula.transporte_embar_15_35 = 1 OR matricula.transporte_embar_15_35 = 0'); + goWaterway_35_Students.group('matricula.transporte_embar_15_35') + req.queryIndex.goWaterway_35_Students = req.querySet.push(goWaterway_35_Students) - 1; + + // Aquaviário/ Embarcação (capacidade mais 35 alunos) + let goWaterwayMoreThan_35 = allTransports.clone(); + goWaterwayMoreThan_35.field('matricula.transporte_embar_35', 'use_transport_id') + goWaterwayMoreThan_35.where('matricula.transporte_embar_35 = 1 OR matricula.transporte_embar_35 = 0'); + goWaterwayMoreThan_35.group('matricula.transporte_embar_35') + req.queryIndex.goWaterwayMoreThan_35 = req.querySet.push(goWaterwayMoreThan_35) - 1; + + // Trêm / Metrô + let goSubwayAndTrain = allTransports.clone(); + goSubwayAndTrain.field('matricula.transporte_trem_metro', 'use_transport_id') + goSubwayAndTrain.where('matricula.transporte_trem_metro = 1 OR matricula.transporte_trem_metro = 0'); + goSubwayAndTrain.group('matricula.transporte_trem_metro') + req.queryIndex.goSubwayAndTrain = req.querySet.push(goSubwayAndTrain) - 1; + + next(); +}, multiQuery, (req, res, next) => { + let transport_match = []; + let transport_match_0 = JSON.parse(JSON.stringify(req.result[req.queryIndex.allTransports])); + let transport_match_1 = JSON.parse(JSON.stringify(req.result[req.queryIndex.allTransports])); + + let all_enrollment_match = []; + let all_enrollment_match_0 = JSON.parse(JSON.stringify(req.result[req.queryIndex.allEnrollment])); + let all_enrollment_match_1 = JSON.parse(JSON.stringify(req.result[req.queryIndex.allEnrollment])); + + //modifica adicionando use_transport_id=false, com os mesmos valores + //do transport_id=true, usado para dar o match e fazer a divisão. + for (let i = 0; i < transport_match_0.length; i++) { + transport_match_0[i].use_transport_id = true; + transport_match.push(transport_match_0[i]) + transport_match_1[i].use_transport_id = false; + transport_match.push(transport_match_1[i]) + } + + //modifica adicionando use_transport_id=false, com os mesmos valores + //do transport_id=true, usado para dar o match e fazer a divisão. + for (let i = 0; i < all_enrollment_match_0.length; i++) { + all_enrollment_match_0[i].use_transport_id = true; + all_enrollment_match.push(all_enrollment_match_0[i]) + all_enrollment_match_1[i].use_transport_id = false; + all_enrollment_match.push(all_enrollment_match_1[i]) + } + + let public_transport = matchQueries(all_enrollment_match, req.result[req.queryIndex.allEnrollmentTransport]); + let van_and_kombi = matchQueries(transport_match, req.result[req.queryIndex.goVansAndKombi]); + let micro_bus = matchQueries(transport_match, req.result[req.queryIndex.goMicroBus]); + let bus = matchQueries(transport_match, req.result[req.queryIndex.goBus]); + let bike = matchQueries(transport_match, req.result[req.queryIndex.goBikes]); + let animal_traction = matchQueries(transport_match, req.result[req.queryIndex.goAnimalTraction]); + let other_vehicle = matchQueries(transport_match, req.result[req.queryIndex.goOtherVehicle]); + let waterway_5_Students = matchQueries(transport_match, req.result[req.queryIndex.goWaterway_5_Students]); + let waterway_15_Students = matchQueries(transport_match, req.result[req.queryIndex.goWaterway_15_Students]); + let waterway_35_Students = matchQueries(transport_match, req.result[req.queryIndex.goWaterway_35_Students]); + let waterway_More_Than_35 = matchQueries(transport_match, req.result[req.queryIndex.goWaterwayMoreThan_35]); + let subway_and_train = matchQueries(transport_match, req.result[req.queryIndex.goSubwayAndTrain]); + + req.result = [{ + public_transport, + van_and_kombi, + micro_bus, + bus, + bike, + animal_traction, + other_vehicle, + waterway_5_Students, + waterway_15_Students, + waterway_35_Students, + waterway_More_Than_35, + subway_and_train + }]; + next(); +}, id2str.multitransform(false), response('transports')); + +module.exports = transportApp; -- GitLab